1、列表解释(list comprehension)
In [50]:
A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5))) A1 = range(10) A2 = [i for i in A1 if i in A0] A3 = [A0[s] for s in A0] A4 = [i for i in A1 if i in A3] A5 = {i:i*i for i in A1} A6 = [[i,i*i] for i in A1]
In [51]:
A0
Out[51]:
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
In [52]:
A1, list(A1) # python3 中range函数是迭代器
Out[52]:
(range(0, 10), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [53]:
A2
Out[53]:
[]
In [54]:
A3
Out[54]:
[1, 2, 3, 4, 5]
In [55]:
A4
Out[55]:
[1, 2, 3, 4, 5]
In [56]:
A5
Out[56]:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
In [57]:
A6
Out[57]:
[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
2、不要让可变参数作为函数的默认参数
In [58]:
def f(x,lst=[]): for i in range(x): lst.append(i*i) print(lst) f(2) f(3,[3,2,1]) f(3)
[0, 1] [3, 2, 1, 0, 1, 4] [0, 1, 0, 1, 4]
第一个函数for循环先后将0和1添加至了空列表lst中。lst是变量的名字,指向内存中存储的一个列表。 第二个函数调用在一块新的内存中创建了新的列表。lst这时指向了新生成的列表,之后再往新列表中添加0、1、2和4。 第三个函数使用了之前内存地址中存储的旧列表。这就是为什么它的前两个元素是0和1了。
3、 参数*args,**kwargs的意思
In [59]:
def f(*args, **kwargs): print('args = ', args) print('kwargs = ', kwargs) lst = [1, 2, 3] tpl = (4, 5, 6) dct = {'a': 7, 'b': 8, 'c': 9}
In [60]:
f()
args = () kwargs = {}
In [61]:
f(1 ,2 ,3)
args = (1, 2, 3) kwargs = {}
In [62]:
f(1, 2, 3, "tian")
args = (1, 2, 3, 'tian') kwargs = {}
In [63]:
f(a=1, b=2, c=3)
args = () kwargs = {'a': 1, 'b': 2, 'c': 3}
In [64]:
f(a=1,b=2, c=3, d='tian')
args = () kwargs = {'a': 1, 'b': 2, 'c': 3, 'd': 'tian'}
In [65]:
f(1, 2, 3, a=1, b=2, c=3)
args = (1, 2, 3) kwargs = {'a': 1, 'b': 2, 'c': 3}
In [66]:
f(*lst, **dct)
args = (1, 2, 3) kwargs = {'a': 7, 'b': 8, 'c': 9}
In [67]:
f(*tpl, **dct)
args = (4, 5, 6) kwargs = {'a': 7, 'b': 8, 'c': 9}
In [68]:
f(1, 2, *tpl)
args = (1, 2, 4, 5, 6) kwargs = {}
In [69]:
f(w='tian', **dct)
args = () kwargs = {'w': 'tian', 'a': 7, 'b': 8, 'c': 9}
In [70]:
f(1, 2, *tpl, w='tian', **dct)
args = (1, 2, 4, 5, 6) kwargs = {'w': 'tian', 'a': 7, 'b': 8, 'c': 9}
In [71]:
def f2(arg1,arg2,*args,**kwargs): print('arg1 = ', arg1) print('arg2 = ', arg2) print('args = ', args) print('kwargs = ', kwargs)
In [72]:
f2(1, 2, 3)
arg1 = 1 arg2 = 2 args = (3,) kwargs = {}
In [73]:
f2(1,2,3,"tian")
arg1 = 1 arg2 = 2 args = (3, 'tian') kwargs = {}
In [74]:
f2(arg1=1,arg2=2,c=3)
arg1 = 1 arg2 = 2 args = () kwargs = {'c': 3}
In [75]:
f2(arg1=1,arg2=2,c=3,w="hi")
arg1 = 1 arg2 = 2 args = () kwargs = {'c': 3, 'w': 'hi'}
In [76]:
f2(1,2,3,a=1,b=2,c=3)
arg1 = 1 arg2 = 2 args = (3,) kwargs = {'a': 1, 'b': 2, 'c': 3}
In [77]:
f2(*lst,**dct)
arg1 = 1 arg2 = 2 args = (3,) kwargs = {'a': 7, 'b': 8, 'c': 9}
In [78]:
f2(*tpl,**dct)
arg1 = 4 arg2 = 5 args = (6,) kwargs = {'a': 7, 'b': 8, 'c': 9}
In [79]:
f2(1,2,*tpl)
arg1 = 1 arg2 = 2 args = (4, 5, 6) kwargs = {}
In [80]:
f2(1,1,w="tian",**dct)
arg1 = 1 arg2 = 1 args = () kwargs = {'w': 'tian', 'a': 7, 'b': 8, 'c': 9}
In [81]:
f2(1,2,*tpl,w="tian",**dct)
arg1 = 1 arg2 = 2 args = (4, 5, 6) kwargs = {'w': 'tian', 'a': 7, 'b': 8, 'c': 9}
如果不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用*args;
如果不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使用**kwargs。
args和kwargs这两个标识符是约定俗成的用法, 也可以用其他标志符代替。
4、@classmethod, @staticmethod, @property的使用
In [89]:
class MyClass(object): def __init__(self): self._some_property = "properties are nice" self._some_other_property = "VERY nice" def normal_method(*args, **kwargs): print("calling normal_method({0},{1})".format(args,kwargs)) @classmethod def class_method(*args, **kwargs): print("calling class_method({0},{1})".format(args,kwargs)) @staticmethod def static_method(*args, **kwargs): print("calling static_method({0}, {1})".format(args, kwargs)) @property def some_property(self, *args, **kwargs): print("calling some_property getter({0},{1},{2})".format(self,args,kwargs)) return self._some_property @some_property.setter def some_property(self, *args, **kwargs): print("calling some_property setter({0},{1},{2})".format(self,args,kwargs)) self._some_property = args[0] @property def some_other_property(self, *args, **kwargs): print("calling some_other_property getter({0},{1},{2})".format(self,args,kwargs)) return self._some_other_property
In [90]:
c = MyClass()
In [97]:
# 未装饰的方法还是正常的行为方式,需要当前的类实例(self)作为第一个参数。 c.normal_method
Out[97]:
>
In [100]:
c.normal_method()
calling normal_method((<__main__.MyClass object at 0x000001A0F5324A20>,),{})
In [101]:
c.normal_method(1, 2, x=3, y=4)
calling normal_method((<__main__.MyClass object at 0x000001A0F5324A20>, 1, 2),{'x': 3, 'y': 4})
In [102]:
# 类方法的第一个参数永远是该类 c.class_method
Out[102]:
>
In [103]:
c.class_method()
calling class_method((,),{})
In [104]:
c.class_method(1,2,x=3,y=4)
calling class_method((, 1, 2),{'x': 3, 'y': 4})
In [105]:
# 静态方法(static method)中除了你调用时传入的参数以外,没有其他的参数。 c.static_method
Out[105]:
In [106]:
c.static_method()
calling static_method((), {})
In [107]:
c.static_method(1,2,x=3,y=4)
calling static_method((1, 2), {'x': 3, 'y': 4})
In [129]:
# @property是实现getter和setter方法的一种方式,当做属性使用 c.some_property
calling some_property getter(<__main__.MyClass object at 0x000001A0F5324A20>,(),{})
Out[129]:
'properties are nice'
In [136]:
# 不能当做方法调用 c.some_other_property()
calling some_other_property getter(<__main__.MyClass object at 0x000001A0F5324A20>,(),{})
--------------------------------------------------------------------------- TypeError Traceback (most recent call last)in 1 # 不能当做方法调用 ----> 2 c.some_other_property() TypeError: 'str' object is not callable
In [137]:
# 设置属性 c.some_property = 'tian'
calling some_property setter(<__main__.MyClass object at 0x000001A0F5324A20>,('tian',),{})
In [138]:
c.some_property
calling some_property getter(<__main__.MyClass object at 0x000001A0F5324A20>,(),{})
Out[138]:
'tian'
In [139]:
# some_other_property 为只读属性, 不能为其设置值 c.some_other_property
calling some_other_property getter(<__main__.MyClass object at 0x000001A0F5324A20>,(),{})
Out[139]:
'VERY nice'
In [140]:
c.some_other_property()
calling some_other_property getter(<__main__.MyClass object at 0x000001A0F5324A20>,(),{})
--------------------------------------------------------------------------- TypeError Traceback (most recent call last)in ----> 1 c.some_other_property() TypeError: 'str' object is not callable
In [142]:
c.some_other_property = 'tian'
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last)in ----> 1 c.some_other_property = 'tian' AttributeError: can't set attribute
注:上面代码为在jupyter notebook中使用