learningPythonV4

python学习手册第四版学习笔记

基础部分

1. list

列表

2. 字典

3.python的类型层次

4. python运算符重载


  1. __slots属性
    类中的这个属性主要是用来限制类的实例不能任意新增属性,只有在列表中的有效,
    如果想制定了slots属性以后,实例还可以新增属性,可以按照下面的方式来写

    class D:
    __slots__  =  ['a','b','__dict__']
    
  2. 装饰器
    装饰器都是一个类,每次使用,都相当于一次实例化.
    比如
    ```python
    class tracer:
    def init(self, func):

    self.calls = 0
    self.func = func
    

    def call(self, *args):

    self.calls += 1
    print("call %s to %s" % (self.calls, self.func.__name__))
    self.func(*args)
    
```python
@tracer
def spam(a, b, c):
    print(a, b, c)
#等效代码
def spam(a,b,c):
    print(a,b,c)
spam=tracer(spam)

因此spam(3,4,5)调用实际上调用的是tracer实例的call

  1. 描述符
    因为Python是一个动态类型解释性语言,不像C/C++等静态编译型语言,数据类型在编译时便可以进行验证,而Python中必须添加额外的类型检查逻辑代码才能做到这一点,这就是描述符的初衷。比如,有一个测试类Test,其具有一个类属性name。

class name_des(object):
    def __init__(self):
        self.__name = None
    def  __get__(self, instance, owner):
        print('call __get__')
        return self.__name
    def  __set__(self, instance, value):
        print('call __set__')
        if  isinstance(value,str):
            self.__name = value
        else:
            raise TypeError("Must be an string")
class test(object):
    name = name_des()

那么执行t.name=3将会报错,这就是描述符的作用,

  1. 属性查找设置伪代码

__getattribute__伪代码:
   __getattribute__(property) logic:
  #先在类(包括父类、祖先类)的__dict__属性中查找描述符
  descripter = find first descripter in class and bases's dict(property)
  if descripter:#如果找到属性并且是数据描述符,就直接调用该数据描述符的__get__方法并将结果返回
      return descripter.__get__(instance, instance.__class__)
  else:#如果没有找到或者不是数据描述符,就去实例的__dict__属性中查找属性,如果找到了就直接返回这个属性值
      if value in instance.__dict__
          return value
      #程序执行到这里,说明没有数据描述符和实例属性,则在类(父类、祖先类)的__dict__属性中查找非数据描述符
      value = find first value in class and bases's dict(property)
      if value is a function:#如果找到了并且这个属性是一个函数,就返回绑定后的函数
         return bounded function(value)
      else:#否则就直接返回这个属性值
         return value
 #程序执行到这里说明没有找到该属性,引发异常,__getattr__函数会被调用
 raise AttributeNotFundedException

 __setattr__伪代码:
 __setattr__(property, value)logic:
 #先在类(包括父类、祖先类)的__dict__属性中查找描述符
 descripter = find first descripter in class and bases's dict(property)
 if descripter:#如果找到了且是数据描述符,就调用描述符的__set__方法
     descripter.__set__(instance, value)
 else:#否则就是给实例属性赋值
     instance.__dict__[property] = value
  1. property

class test(object):
 def __init__(self):
  self.__x=None
 
 @property
 def x(self):
  return self.__x
 @x.setter
 def x(self,value):
  self.__x=value
 @x.deleter
 def x(self):
  del self.__x

用例

t=test()
#会调用def x(self)
t.x
#会调用def x(self,value)
t.x=3
#会调用def x(self)
del t.x