[关闭]
@nemos 2017-05-05T14:54:40.000000Z 字数 6302 阅读 738

对象深入

py


类定义

元类->类->实例

  1. newtype = type(name, bases, dict) #返回一个新类型

直接定义在类内部的变量是绑定在类上面的
init中用self的是绑定在对象上面的
直接定义在类内部的为实例方法
类调用则为未绑定


隐藏成员

类的成员加上双下划线即可外部无法直接访问

  1. Secretive.__inaccessible <=>
  2. Secretive._Secretive__inaccessible

super

函数签名: super([type[, object-or-type]])

  1. #旧式类
  2. class SongBird(Bird):
  3. def __init__(self):
  4. Bird.__init__(self)
  5. #新式类
  6. class SongBird(Bird):
  7. def __init__(self):
  8. super(SongBird, self).__init__()

官方文档的示例代码

  1. class C(B):
  2. def method(self, arg):
  3. super().method(arg) # This does the same thing as:
  4. # super(C, self).method(arg)

属性

特殊属性

  1. obj.__bases__ #返回子类
  2. obj.__dict__ #包含实例属性的字典,以及类的所有可调用方法
  3. #可以代替普通的赋值操作
  4. #对象的__dict__为普通的字典,而类的为dictproxy
  5. obj.__class__ #获取对象类型即从哪里被实例化出来
  6. obj.__doc__ #显示文档信息
  7. obj.__module__ #显示当前操作的对象在哪个模块
  8. obj.__metaclass__ #指定类由谁实例化

函数原型

  1. property attr=property(fget=None, fset=None, fdel=None, doc=None)

使用方法

  1. class obj():
  2. def setValue():
  3. pass
  4. def getValue():
  5. pass
  6. #使用property函数
  7. value = property(getValue, setValue)

实现

  1. class Property(object):
  2. "Emulate PyProperty_Type() in Objects/descrobject.c"
  3. def __init__(self, fget=None, fset=None, fdel=None, doc=None):
  4. self.fget = fget
  5. self.fset = fset
  6. self.fdel = fdel
  7. if doc is None and fget is not None:
  8. doc = fget.__doc__
  9. self.__doc__ = doc
  10. def __get__(self, obj, objtype=None):
  11. if obj is None:
  12. return self
  13. if self.fget is None:
  14. raise AttributeError("unreadable attribute")
  15. return self.fget(obj)
  16. def __set__(self, obj, value):
  17. if self.fset is None:
  18. raise AttributeError("can't set attribute")
  19. self.fset(obj, value)
  20. def __delete__(self, obj):
  21. if self.fdel is None:
  22. raise AttributeError("can't delete attribute")
  23. self.fdel(obj)
  24. def getter(self, fget):
  25. return type(self)(fget, self.fset, self.fdel, self.__doc__)
  26. def setter(self, fset):
  27. return type(self)(self.fget, fset, self.fdel, self.__doc__)
  28. def deleter(self, fdel):
  29. return type(self)(self.fget, self.fset, fdel, self.__doc__)

访问顺序

  1. 如果attrname是一个objectname的特殊(例如,Python提供的)属性,返回它;
  2. 检查objectname.class.dict中的attrname。如果它存在并且是一个数据描述符,返回这个描述符本身。搜索所有objectname.class的基类并做相同的操作;
  3. 检查objectname.dict中的attrname,如果找到即返回。如果objectname是一个类,同时搜索它的基类。如果它是类并且一个描述符存在其中或是基类中,返回这个描述符的结果;
  4. 检查objectname.class.dict中的attrname。如果存在并且是一个非数据描述符,返回这个描述符的结果。如果存在并且不是一个描述符,直接返回。如果是存在并且是一个数据描述符,我们不应当来这里因为我们应当已经在第二步时返回了。搜索所有的objectname.class的基类并做同样的操作。
  5. 抛出AttributeError异常。

属性设置

  1. 检查objectname.class.dict中的attrname属性。如果存在并且是一个数据描述符,使用描述符来设置值。搜索所有objectname.class的基类并做相同的操作。
  2. 向objectname.dict的attrname键插入一些内容。

类函数

  1. bool = callable(obj) #判断对象是否可以被调用
  2. #py3 中是hasattr()
  3. bool = getattr(obj, name[, default]) #确定属性值
  4. bool = hasattr(obj, name)
  5. None = setattr(obj, name, value)
  6. bool = isinstance(obj, class)
  7. issubclass(subclass, class)
  8. type = type(obj)

特殊方法

  1. @staticmethod #静态方法
  2. @classmethod #类方法
  3. #类方法可以用类的具体具体对象直接调用
  4. #第一个参数传入调用的类

魔术方法

构造

  1. obj.__new__(self) #创建类实例并返回
  2. obj.__init__(self) #初始化实例
  3. obj.__del__(self) #构析函数

访问

控制属性的访问的方法

  1. obj.__getattribute__(self, name) #当name被访问时调用,不管存在与否
  2. obj.__getattr__(self, name) #当name被访问且不存在时,在被调用前先调用__getattribute__
  3. obj.__setattr__(self, name, value) #当name被赋值时调用
  4. obj.__delattr__(self, name) #删除时调用

无限递归错误

  1. def __setattr__(self, name, value): #错误用法
  2. self.name = value
  3. # 每当属性被赋值的时候(如self.name = value), ``__setattr__()`` 会被调用,这样就造成了递归调用。
  4. # 这意味这会调用 ``self.__setattr__('name', value)`` ,每次方法会调用自己。这样会造成程序崩溃。
  5. def __setattr__(self, name, value): #正确用法
  6. self.__dict__[name] = value # 给类中的属性名分配值

容器

  1. obj.__len__(self, key) #返回容器长度
  2. obj.__getitem__(self, key) #self[]产生的行为,可以用[]传入数据,或[::]传入切片对象,以及字符串等等
  3. # 以上两个方法实现不可变容器,加上以下实现可变容器
  4. obj.__setitem__(self, key, value) # self[key] = value 产生的行为
  5. obj.__delitem__(self, key) #删除元素 #del self[key]的实现
  6. obj.__iter__(self) #返回容器迭代器, for x in self时调用
  7. obj.__reversed__(self)
  8. obj.__contains__(self, item) # in时产生的行为,若没有定义会从迭代对象中一个一个找
  9. obj.__missing__(self, key) #找不到元素时触发的行为

反射

  1. obj.__instancecheck__(self, instance) #检查一个实例是不是你定义的类的实例
  2. obj.__subclasscheck__(self, subclass) #检查一个类是不是你定义的类的子类

函数

  1. obj.__call__(self, *args, *kwargs) #函数对象
  1. class Entity:
  2. "调用实体来改变实体的位置"
  3. def __init__(self, size, x, y):
  4. self.x, self.y = x, y
  5. self.size = size
  6. def __call__(self, x, y):
  7. "改变实体的位置"
  8. self.x, self.y = x, y

上下文管理

  1. with open('foo.txt') as bar:
  2. # do something with bar
  1. obj.__enter__(self)
  2. obj.__exit__(self, exception_type, exception_value, traceback)

描述器

  1. obj.__str__(self) #print时显示的内容
  2. obj.__add__(self, other) #加法操作

描述器

描述器是通过获取、设置以及删除的时候被访问的类。

  1. # instance是拥有该描述器对象的一个实例。owner是拥有者本身
  2. value = descr.__get__(self, ins, owner) #当描述器的值被取得的时候的行为
  3. None = descr.__set__(self, ins, value) #定义了当描述器的值被改变的时候的行为
  4. None = descr.__delete(self, ins) #定义了当描述器的值被删除的时候的行为

实现了get的为非数据描述符
同时实现get,set的为数据描述符

实现例子

  1. class Meter(object):
  2. def __init__(self, value=0.0):
  3. self.value = float(value)
  4. def __get__(self, instance, owner):
  5. return self.value
  6. def __set__(self, instance, value):
  7. self.value = float(value)
  8. class Foot(object):
  9. def __get__(self, instance, owner):
  10. return instance.meter * 3.2808
  11. def __set__(self, instance, value):
  12. instance.meter = float(value) / 3.2808
  13. class Distance(object): #用米和英寸来表示两个描述器之间的距离
  14. meter = Meter(10)
  15. foot = Foot()
  16. ########################
  17. >>>d = Distance()
  18. >>>print d.foot
  19. >>>print d.meter
  20. 32.808
  21. 10.0

复制

  1. obj.__copy__(self) #当ins.copy()被调用时产生的行为
  2. obj.__deepcopy__(self, memodict={}) #当ins.deepcopy()被调用时产生的行为

比较

  1. __cmp__(self, other) #是比较方法里面最基本的的魔法方法
  2. __eq__(self, other) #定义相等符号的行为,==
  3. __ne__(self,other) #定义不等符号的行为,!=
  4. __lt__(self,other) #定义小于符号的行为,<
  5. __gt__(self,other) #定义大于符号的行为,>
  6. __le__(self,other) #定义小于等于符号的行为,<=
  7. __ge__(self,other) #定义大于等于符号的行为,>=

单目运算

  1. __pos__(self) #实现一个取正数的操作
  2. __neg__(self) #实现一个取负数的操作
  3. __abs__(self) #实现一个内建的abs()函数的行为
  4. __invert__(self) #实现一个取反操作符(~操作符)的行为
  5. __round__(self, n) #实现一个内建的round()函数的行为
  6. __floor__(self) #实现math.floor()的函数行为
  7. __ceil__(self) #实现math.ceil()的函数行为
  8. __trunc__(self) #实现math.trunc()的函数行为

双目运算

  1. __add__(self, other) #实现一个加法
  2. __sub__(self, other) #实现一个减法
  3. __mul__(self, other) #实现一个乘法
  4. __floordiv__(self, other) #实现一个“//”操作符产生的整除操作()
  5. __div__(self, other) #实现一个“/”操作符代表的除法操作
  6. __truediv__(self, other) #实现真实除法
  7. __mod__(self, other) #实现一个“%”操作符代表的取模操作
  8. __divmod__(self, other) #实现一个内建函数divmod()
  9. __pow__ #实现一个指数操作(“**”操作符)的行为
  10. __lshift__(self, other) #实现一个位左移操作(<<)的功能
  11. __rshift__(self, other) #实现一个位右移操作(>>)的功能
  12. __and__(self, other) #实现一个按位进行与操作(&)的行为
  13. __or__(self, other) #实现一个按位进行或操作的行为
  14. __xor__(self, other) #__xor__(self, other)

增量运算

  1. __iadd__(self, other) #加法赋值
  2. __isub__(self, other) #减法赋值
  3. __imul__(self, other) #乘法赋值
  4. __ifloordiv__(self, other) #整除赋值,地板除,相当于 //= 运算符
  5. __idiv__(self, other) #除法赋值,相当于 /= 运算符
  6. __itruediv__(self, other) #真除赋值
  7. __imod_(self, other) #模赋值,相当于 %= 运算符
  8. __ipow__ #乘方赋值,相当于 **= 运算符
  9. __ilshift__(self, other) #左移赋值,相当于 <<= 运算符
  10. __irshift__(self, other) #左移赋值,相当于 >>= 运算符
  11. __iand__(self, other) #与赋值,相当于 &= 运算符
  12. __ior__(self, other) #或赋值
  13. __ixor__(self, other) #异或运算符,相当于 ^= 运算符

类型转换

  1. __int__(self) #转换成整型
  2. __long__(self) #转换成长整型
  3. __float__(self) #转换成浮点型
  4. __complex__(self) #转换成 复数型
  5. __oct__(self) #转换成八进制
  6. __hex__(self) #转换成十六进制
  7. __index__(self) #如果你定义了一个可能被用来做切片操作的数值型,你就应该定义__index__
  8. __trunc__(self) #当 math.trunc(self) 使用时被调用__trunc__返回自身类型的整型截取
  9. __coerce__(self, other) #执行混合类型的运算
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注