python之面向对象进阶

通过定义具有特殊名字的方法,类能够实现某些特殊语法的调用操作(例如+-*/操作运算,切片等等)。

C.init(self) 构造器
C.new(self) 构造器,通常用在设置不可变数据类型的子类
C.del(self) 析构器
C.str(self) 用于print函数及str函数
C.repr(self) 用于repr函数和操作符 ’ ’
C.unicode(self) 用于Unicode字符串输出,内建unicode
C.call(self) 用于将对象变为可调用
C.nonzero(self) 将obj定于False值,用于内建bool
C.len(self) 用于len函数,可用于类
对象值比较
C.cmp(self, obj) 对象比较,用于cmp函数
C.lt(self, obj) 对应<,<=操作符
C.gt(self, obj) 对应>,>=操作符
C.eq(self, obj) 对应==,!=及<>操作符
属性相关(通过点操作)
C.getattr(self, attr) 获取属性;内建 getattr();仅当属性没有找到时调用
C.setattr(self, attr, val) 设置属性
C.delattr(self, attr) 删除属性
C.getattribute(self, attr) 获取属性;内建 getattr();总是被调用
描述符方法
C.get(self, attr) a (描述符)获取属性
C.set(self, attr, val) a (描述符)设置属性
C.delete(self, attr) a (描述符)删除属性
数值类型:二进制操作符
C.*add(self, obj) 加;+操作符
C.*sub(self, obj) 减;-操作符
C.mul(self, obj) 乘;操作符
C.*div(self, obj) 除;/操作符
C.*truediv(self, obj) e True 除;/操作符
C.*floordiv(self, obj) e Floor 除;//操作符
C.*mod(self, obj) 取模/取余;%操作符 C
C.*divmod(self, obj) 除和取模;内建 divmod()
C.pow(self, obj[, mod]) 乘幂;内建 pow();*操作符
C.*lshift(self, obj) 左移位;<<操作符
C.*rshift(self, obj) 右移;>>操作符
C.*and(self, obj) 按位与;&操作符
C.*or(self, obj) 按位或;|操作符
C.*xor(self, obj) 按位与或;^操作符
数值类型:一元操作符
C.neg(self) 一元负
C.pos(self) 一元正
C.abs(self) 绝对值;内建 abs()
C.invert(self) 按位求反;~操作符
数值类型:数值转换
C.complex(self, com) 转为 complex(复数);内建 complex()
C.int(self) 转为int;内建 int()
C.long(self) 转为long;内建 long()
C.float(self) 转为float;内建 float()
数值类型:基本表示法(String)
C.oct(self) 八进制表示;内建 oct()
C.hex(self) 十六进制表示;内建 hex() 数
数值类型:数值压缩
C.coerce(self, num) 压缩成同样的数值类型;内建 coerce()
C.index(self)g 在有必要时,压缩可选的数值类型为整型(比如:用于切片 索引等等)
序列类型(通过[]操作属性)
C.len(self) 序列中项的数目
C.getitem(self, ind) 得到单个序列元素 C.setitem(self, ind,val) 设置单个序列元素 C.delitem(self, ind) 删除单个序列元素
C.getslice(self, ind1,ind2) 得到序列片断 C.setslice(self, i1, i2,val) 设置序列片断 C.delslice(self, ind1,ind2) 删除序列片断 C.contains(self, val) f 测试序列成员;内建 in 关键字 C.*add(self,obj) 串连;+操作符
C.mul(self,obj) 重复;操作符
C.iter(self) e 创建迭代类;内建 iter()
映射类型
C.len(self) mapping 中的项的数目
C.hash(self) 散列(hash)函数值
C.getitem(self,key) 得到给定键(key)的值 C.setitem(self,key,val) 设置给定键(key)的值 C.delitem(self,key) 删除给定键(key)的值 C.missing(self,key) 给定键如果不存在字典中,则提供一个默认值

包装:

对一个已存在的对象,增加新的,删除不要的或者修改其它已存在的功能。

授权:

即所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性(关键点是覆盖getattr()方法)。

描述符

任何实现get(),set()及delete()方法中的一个方法的新式类就称为描述符。
数据描述符:至少实现了get()和set(),非数据描述符:没有实现set()。
如果你想要为一个属性写个代理,必须把它作为一个类的属性,让这个代理来为我们做所有的 工作。当你用这个代理来处理对一个属性的操作时,你会得到一个描述符来代理所有的函数功能。 属性访问的默认行为是从一个对象的字典中获取、设置或删除属性,例如,a.x有一个查找链,从a.dict[‘x’]开始,然后是type(a).dict[‘x’],然后继续在type(a)的基类中查找,元类除外。
使用描述符的顺序很重要,有一些描述符的级别要高于其它的。整个描述符系统的心脏是 getattribute(),因为对每个属性的实例都会调用到这个特殊的方法。这个方法被用来查找类 的属性,同时也是你的一个代理,调用它可以进行属性的访问等操作。
函数是非数据描述符,实例属性有更高的优先级,我们可以遮蔽任一个非数据描述符,只需简单的把一个对象赋给实例(使用相同的名字)就可以了。
由于getattribute()的实现方式很特别,我们在此对getattribute()方法的执行方式 做一个介绍。因此了解以下优先级别的排序就非常重要了:

  • 类属性
  • 数据描述符
  • 实例属性
  • 非数据描述符
  • 默认为getattr()

描述器是一个强大的通用协议。它们是属性、方法、静态方法、类方法和super()背后的机制。
要记住的重点是:

  • 描述器由getattribute()方法调用
  • 覆盖getattribute()会阻止描述器自动调用
  • object .getattribute()和type .getattribute()对get()进行不同的调用。
  • 数据描述器总是覆盖实例字典。
  • 非数据描述器可能被实例字典覆盖。

静态属性property的使用方式:

方法一:
class C(object):
    def getx(self): return self.__x
    def setx(self, value): self.__x = value
    def delx(self): del self.__x
    x = property(getx, setx, delx, "I'm the 'x' property.")
方法二:
class C(object):
    @property
    def x(self): 
        return self.__x
    @x.setter
    def x(self, value): 
        self.__x = value
    @x.deleter
    def x(self): 
        del self.__x

_slots_属性

slots声明接受一个实例变量的序列并且在每个实例中只保留为每个变量保存一个值的空间。空间被省下来了是因为不会为每个实例创建dict
使用slots注意事项:

  • 如果继承自一个没有slots的类,该类的dict属性将始终可以访问,所以在子类中定义slots毫无意义。
  • 没有dict变量,实例不可以给不在slots中定义的新变量赋值。尝试给没有列出的变量名赋值将引发AttributeError。如果需要动态地给新的变量赋值,那么可以在slots的声明的字符串序列中增加’dict‘。
  • 因为每个实例都没有weakref变量,定义slots 的类不支持对其实例的弱引用。如果需要支持弱引用,可以在slots声明的字符串序列中增加’weakref‘。
  • slots在类级别上实现,通过为每个变量名创建描述器(实现描述器)。结果,类属性不可以用于设置slots定义的实例变量的默认值;否则,该类属性将覆盖描述器的赋值。
  • slots定义的动作只限于它所定义的类。结果,字典将具有dict,除非它们也定义了slots(必须只能包含额外的slots名称)。
  • 如果类定义了一个在基类中定义了的slot,基类slot定义的实例变量将不可访问(除非直接从基类获取它的描述器)。这致使程序的含义无法定义。在未来,可能会增加一个检查来防止这个行为。
  • 非空的slots对于从“可变长度”的内建类型例如long、str和tuple继承的类不能工作。
  • 非字符串形式的可迭代类型可以赋值给slots。映射也可以使用;然而,在未来,可能对每个键对应的值赋予特殊的含义。
  • class赋值只有在两个类具有相同的slots是才工作。

元类

元类可以理解为类的类,所有的类都是由元类实例化生成。我们平时直接定义的类都是由type这个元类生成,如果我们想增加其它自己想要的功能在类里,我们可以定制化自己的元类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值