python中几个基础而又重要的知识点

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中使用

你可能感兴趣的:(学习笔记)