Python学习杂记
摘要:
1.self
2.zip函数
3.*list/tuple
4.super继承说明
5.数据库事务
6.functools模块
7.* args和**kwargs
8.with语句
self:
self在python中不是关键词,可以定义成其他合法的字符串,但是最好写成self,符合规范。
=>
class Person: def _init_(myname,name): myname.name=name def sayhello(myname): print 'My name is:',myname.name p=Person('Bill') print p
上面的myname就是一个self的替代。
self指的是类实例对象本身,不是类本身。
=>
class Person: def _init_(self,name): self.name=name def sayhello(self): print 'My name is:',self.name p=Person('Bill') print p
self指向类实例对象本身,不是类本身的理由
class Person: def _init_(self,name): self.name=name def sayhello(self): print 'My name is:',self.name p=Person('Bill') p1 = Person('Apple') print p
如果self指向类对象,当有多个实例对象时,会无法确定其指向哪一个。
- self代表当前对象的地址。self能避免非限定调用造成的全局变量。在类的方法内才能使用,一般为额外的第一个参数。
- 原理:当创建一个类MyClass,实例化MyClass得到了MyObject这个对象,然后调用这个对象的方法MyObject.method(arg1,arg2) ,这个过程中,Python会自动转为Myclass.mehod(MyObject,arg1,arg2)
zip函数
- zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表。
具体参考:Zip
*list/tuple
- 在函数调用中使用*list/tuple的方式表示将list/tuple分开,作为位置参数传递给对应函数(前提是对应函数支持不定个数的位置参数)
super继承说明
- super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,产生了一个super对象;
- super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
- super(B, self).func的调用并不是用于调用当前类的父类的func函数;
- Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);
- 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。
- 详细参考:推荐!、参考
数据库事务
数据库事务是指作为单个逻辑工作单元执行的一系列操作,可以认为事务就是一组不可分割的SQL语句
functools模块
- 这个模块主要有三个函数:partial(),update_wrapper()和wraps()
partial(function[,*args[,**kwargs]])
创建一个类似函数的对象partial,当调用该对象时,会使用位置参数args、关键字参数kwargs和任何附加位置或关键字参数来调用function。附加的位置参数添加到args末尾,附加的关键字参数合并到kwargs中,覆盖以前的任何值(如果有))。当执行大量函数调用且许多参数都是固定时,一般会使用partial()
例如,我们要把python中的int([x[,base]])函数,演变为把所有输入的二进制数转为整型(原函数是将一个字符串转换为普通的整形),我们只需要
from functools import partial int2 = partial(int,base=2) print int2('11') # 3 print int2('111') # 7
update_wrapper(wrapper,wrapped [,assigned [, updated]])
- 将函数wrapped的属性赋值到包装器函数wrapper,使包装的函数类似于原始函数。即把被封装的函数的module,name,doc和dict复制到封装的函数中去
- 将函数wrapped的属性赋值到包装器函数wrapper,使包装的函数类似于原始函数。即把被封装的函数的module,name,doc和dict复制到封装的函数中去
wraps(function [, assigned [,updated]])
- 装饰器,与update_wrapper()类似。(源码上,它只是用partial()把update_wrapper()给封装了一下)
- 装饰器小解
如何使用:
from functools import wraps def my_decorator(f): @wraps(f) def wrapper(*args, **kwds): print 'Calling decorated function' return f(*args, **kwds) return wrapper @my_decorator def example(): """这里是文档注释""" print 'Called example function' example() # 下面是输出 """ Calling decorated function Called example function """ print example.__name__ # 'example' print example.__doc__ # '这里是文档注释'
python中的 * args和**kwargs
看例子:
def foo(*args, **kwargs):
print 'args = ', args
print 'kwargs = ', kwargs
print '---------------------------------------'
if __name__ == '__main__':
foo(1,2,3,4)
foo(a=1,b=2,c=3)
foo(1,2,3,4, a=1,b=2,c=3)
foo('a', 1, None, a=1, b='2', c=3)
输出结果如下:
args = (1, 2, 3, 4)
kwargs = {}
---------------------------------------
args = ()
kwargs = {'a': 1, 'c': 3, 'b': 2}
---------------------------------------
args = (1, 2, 3, 4)
kwargs = {'a': 1, 'c': 3, 'b': 2}
---------------------------------------
args = ('a', 1, None)
kwargs = {'a': 1, 'c': 3, 'b': '2'}
---------------------------------------
可以发现* args表示任何多个无名参数,它是一个tuple;* kwargs表示关键字参数,它是一个dict。 并且同时使用 args和* kwargs时,必须 args参数列要在** kwargs前,像foo(a=1, b=’2’, c=3, a’, 1, None, )这样调用的话,会提示语法错误“SyntaxError: non-keyword arg after keyword arg”。
with语句
- 要使用with语句,首先要明白上下文管理器。有了上下文管理器,with语句才能工作
- 上下文管理协议(Context Management Protocol):包含方法 enter() 和 exit(),支持该协议的对象要实现这两个方法。
- 上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了enter() 和 exit() 方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,
也可以通过直接调用其方法来使用。 - 运行时上下文(runtime context):由上下文管理器创建,通过上下文管理器的 enter() 和exit() 方法实现,enter() 方法在语句体执行之前进入运行时上下文,exit() 在语句体执行完后从运行时上下文退出。with 语句支持运行时上下文这一概念。
- 上下文表达式(Context Expression):with 语句中跟在关键字 with 之后的表达式,该表达式要返回一个上下文管理器对象。
- 语句体(with-body):with 语句包裹起来的代码块,在执行语句体之前会调用上下文管
理器的 enter() 方法,执行完语句体之后会执行 exit() 方法。
代码示例:
with expression as variable: with block
该代码快的执行过程是:
- 1.先执行expression,然后执行该表达式返回的对象实例的enter函数,然后将该函数的返回值赋给as后面的变量。(注意,是将enter函数的返回值赋给变量)
- 2.然后执行with block代码块,不论成功,错误,异常,在with block执行结束后,会执行第一步中的实例的exit函数。
- 参考:浅析with