python的学习小结
__all__
的用法
常常看源码发现__init__.py
文件中有__all__
,关于它的用法举个栗子:
__all__ = ['bar', 'baz']
waz = 5
bar = 10
def baz():
return 'baz'
__all__
仅仅影响from foo import *
,会认为没在__all__
中的对象无法导入.
from foo import *
print bar
print baz
# waz将会报异常
print waz
但如果使用from foo import waz
,则能够导入waz.
classmethod与staticmethod
类方法classmethod常用来创建一个类的实例,非常像c++中的构造函数.
class C:
@staticmethod
def f(cls, arg1, arg2, ...): # 第一个参数为cls
cls_ = cls(arg1, arg2)
return cls_
静态方法staticmethod可以被类调用C.f()
或实例调用C().f()
.用于常驻内存,并与实例无关的公共方法场景.
class C:
@staticmethod
def f(arg1, arg2, ...):
pass
uuid
uuid(UUID objects according to RFC 4122),工作中常使用uuid模块来产生唯一通用标示符,代表不同的用户.
import uuid
uuid1()
uuid2()
uuid3()
uuid4()
super()
调用父类方法时.
class C(B):
def method(self, arg):
super(C, self).method(arg)
等价于:
class C(B):
def method(self, arg):
super().method(arg)
super()
只能super().__getitem__(name)
来显式调用方法,不能super()[name]
这样的隐式调用.
isinstance(a, (b, c, d))
是下面方式的优雅的表达:
if type(a) in (b, c, d):
return True
else
return False
创建class
class X:
a = 1
等价于
X = type('X', (object,), dict(a=1))
class type(name, bases, dict)
name是类名,bases是父类,dict是成员的字典.
字典类型初始化
d = {'a':1}
d.get('b',2) # b不在字典d中,获取时初始化b为2
locals()查看本地变量
注释会在__doc__
出现,申明的变量直接出现,__file__
是文件绝对路径.
{
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fbdc7a04278>,
'__doc__': '\n all is here\n',
'__file__': '/home/kushao1267/workspace/restless/restless/ss.py',
'a': [1, 2, 3], # 申明的变量
'__package__': None,
'__cached__': None,
'__name__': '__main__',
'__builtins__': <module 'builtins' (built-in)>,
'__spec__': None
}
zip与unzip
a = [1, 2, 3]
b = [4, 5, 6]
def zip_func(a, b):
"""
[1, 2, 3],[4, 5, 6] --> [(1, 4), (2, 5), (3, 6)]
"""
zip_ = list(zip(a, b))
return zip_
def unzip_func(zip_):
"""
[(1, 4), (2, 5), (3, 6)] --> [(1, 2, 3), (4, 5, 6)]
"""
a, b = list(zip(*zip_)) # zip(*) 是解压
return list(a), list(b)
if __name__ == '__main__':
zip_ = zip_func(a, b)
a, b = unzip_func(zip_)
print(zip_, a, b)
关键词使用
常常在开发中使用python已有的关键词,例如class,type,所以我们常常用class_
,type_
以区分,因为class和type都是对象,能够被赋值,后面coding时容易出现错误.
try...except...else语句
try:
todo
except:
# catch Exception
else:
todo # try未触发异常时执行此处
python下的路径
import os
def function():
print(os.path.abspath(__file__)) # 当前脚本所在绝对路径
print(os.path.dirname(os.path.abspath(__file__))) # 当前脚本所在的路径
print(os.path.dirname(os.path.dirname(
os.path.abspath(__file__)))) # 当前脚本所在的上移级路径
if __name__ == '__main__':
function()
输出为
/home/kushao1267/ss_work/test.py
/home/kushao1267/ss_work
/home/kushao1267
[Finished in 0.3s]
所以,__file__
代表即为当前脚本文件,os.path.abspath()
方法获取一个文件的绝对路径,os.path.dirname()
获取其路径名或上一级路径名.
itertools的chain()
很多时候需要对不同的容器中的对象进行相同处理
import itertool
a = [1,2,3]
b= [3,4,5]
for i in itertool.chain(a,b):
print(i)
而下面的方式内存消耗将会大很多,因为会创建a+b的一个容器
for i in a+b:
print(i)
with语句
with语句的上下文context是通过栈来实现嵌套的.
比如:
with A() as a, B() as b:
suite
等价于
withA()asa:
withB()asb:
suite
上下文管理器contextmanager
@contextlib.contextmanager 修饰器可用于with语句中,且免于自己定义__enter__()
和__exit__()
方法
例如:
fromcontextlibimportcontextmanager
@contextmanager
deftag(name):
print("<%s>"%name)//此处的code相当于__enter__()
yield//等待todo语句完成
print("</%s>"%name)//此处的code相当于__exit__()
>>>withtag("h1"):
... print("foo")//todo语句
...
<h1>
foo
</h1>
上下文装饰器ContextDecorator
定义上下文装饰器
from contextlib import ContextDecorator
class mycontext(ContextDecorator):
def __enter__(self):
print('Starting')
return self
def __exit__(self, *exc):
print('Finishing')
return False
装饰器方式如下:
>>> @mycontext()
... def function():
... print('The bit in the middle')
...
>>> function()
Starting
The bit in the middle
Finishing
with语句方式如下:
>>> with mycontext():
... print('The bit in the middle')
...Starting
The bit in the middle
Finishing
function()中的内容将在继承ContextDecorator的装饰器mycontext()的__enter__()
与__exit__()
之间执行.