# 3.0 后不继承任何类默认继承 Object, python 2.2 新增的新式继承方法
class MyClass:
# __new__ 是一个 static method, args 是传入的参数 为 tuple类型, kwargs 为 dict 类型
def __new__(cls, *args, **kwargs):
print('new method', args, kwargs)
# 不能用 MyClass() 会死循环
return object.__new__(MyClass)
def __init__(self, name, g):
self.name = name
self.g = g
print('init method')
# 这里创建一根 MyClass 的对象, 首先会调用 __new__ 生产一个对象, 再调用 __init__ 进行一些初始化操作
# 自己没实现, 则会调用父类的 方法
o = MyClass("asdasd", "b")
# new method ('asdasd', 'b') {}
# init method
# 最终继承至 Object class
print(MyClass.mro()) # [, ]
析构函数, 对象生命周期即将消失时调用的方法, 也有可能在 __del__
方法里面对对象进行再一次的引用(不推荐), 这种做法叫做resurrection
(耶稣复活), 这样析构函数就可能被调用多次, 目前 CPython 中的实现只会调用一次
都是美化对象的输出, 如果同时实现这两个方法, 会只输出__str__
方法中返回的字符串
返回一个在进行占位的字符串, 有额外参数formatspec
文档
def __format__(self, format_spec):
return "MyClassFormat"
使用bytes
函数时会调用此方法, 返回 bytes string
针对比较运算符的方法
object.__lt__(self, other) # less than
object.__le__(self, other) # less equal
object.__eq__(self, other) # equal
object.__ne__(self, other) # not equal
object.__gt__(self, other) # greater than
object.__ge__(self, other) # greater equal
可以自定义哈希值
对 bool()
函数所响应的方法, 返回一个 bool 值
对于找不到对应的属性的, 就会响应的方法
print(o, o.ss) # o.ss 并不存在
访问属性的时候就会调用, 并且会覆盖掉 __getattr__
给属性赋值的时候触发
使用 del
关键字时会触发
使用dir()
函数会触发, 必须返回一个队列
只能是 types.ModuleType
的子类
目前不明白的这个属性的意义在哪(还太菜)
通过 实现__get__
与__set__
和__delete__
及__set_name__
(3.6 新增)来完成一个描述符类
class Desc:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
print("__get__", instance, owner)
def __set__(self, instance, value):
print("__set__", instance, value)
def __delete__(self, instance):
print("__delete__", instance)
def __set_name__(self, owner, name):
print("__set_name__", owner, name)
class Td:
c = Desc("cai")
t = Td() # __set_name__ c
t.c # __get__ <__main__.Td object at 0x100ae56a0>
t.c = "nihao" # __set__ <__main__.Td object at 0x100ae56a0> nihao
t.c = "nibuhao" # __set__ <__main__.Td object at 0x100ae56a0> nibuhao
del t.c # __delete__ <__main__.Td object at 0x100ae56a0>
暂时没想到有什么应用场景
限制 class 添加的属性名 __slots__ = ('name')
, 就可以禁止 class 动态绑定属性 name
继承之其他类的时候回触发的类方法, 可以自己添加参数
class Super:
name = ""
def __init_subclass__(cls, name, **kwargs):
super.__init_subclass__(**kwargs)
cls.name = name
class InitSub(Super, name="123"):
pass
i = InitSub()
print(i, i.name) # <__main__.InitSub object at 0x10a2be6a0> 123
stackoverflow 上有大佬写了很详细的解答英文和中文
使用 isinstance(instance, class)
会调用
使用 issubclass(subclass, class)
会调用
当一个对象被当成函数来调用时, 此方法会被调用
class Callable:
def __call__(self, *args, **kwargs):
print(args) # ('as', 1, 3)
c = Callable()
c("as", 1, 3)
len()
时触发, 返回一个大于 0 的整数
模仿队列的时候 key
只能是整数或者一个 slice
对象
dict 子类找不到对应的 key 则会触发此方法
进行赋值操作, 仅在给旧的 key 赋值或者增加新的 key 时才有效
移除某个 key 和 value
需要返回一个可迭代的对象iter()
调用 reversed() 函数时会调用
使用测试操作符 in
和 not in
时会触发此方法
object.__add__(self, other) 对应 +
object.__sub__(self, other) 对应 -
object.__mul__(self, other) 对应 *
object.__matmul__(self, other) 对应 @
(矩阵乘法)
object.__truediv__(self, other) 对应 /
(整数除法)
object.__floordiv__(self, other) 对应 //
(浮点数除法)
object.__mod__(self, other) 对应 %
object.__divmod__(self, other) 对应 divmod()
示例
object.__pow__(self, other[, modulo]) 对应 pow()
幂计算
位操作
object.__lshift__(self, other) 对应 <<
左移
object.__rshift__(self, other) 对应 >>
右移
object.and(self, other) 对应 &
且
object.__xor__(self, other) 对应 ^
异或
object.__or__(self, other) 对应 |
或
如果没实现的响应
object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rmatmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other)
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)
还有一些就不一一列举了, 大多类似
参考:
https://docs.python.org/3/reference/datamodel.html#special-method-names