方法
属性方法
概念
属性方法即使用@property
装饰器,将函数中的方法转化为”属性”,即可以直接使用访问属性的方式,即属性名.方法
进行方法的调用。
内置函数property
及@property
property
函数
property函数的作用是托管类的属性。
1 | class C: |
@property
装饰器
1 | # 下面类与上述例子具有相同的效果 |
类方法(@classmethod)
概念
类方法的调用可以在类上进行也可以在实例上进行。
@classmethod装饰器将一个方法封装成类方法。
意义
- python中的类方法解决了python中不可以通过不同的参数来重载不同的构造函数的问题。即python可以通过类方法实现在实例化前进行某些操作,进而实现类似于多个构造函数的效果。
- 对于某些需要在类实例化之前做些交互操作提供实现方法。
- 在继承的时,保证了子类使用可选构造函数构造出来的类是子类的实例而不是父类的实例。
示例
1 | class Foo(object): |
静态方法
概念
静态方法的调用可以在类上进行也可以在实例上进行。
意义
静态方法其本质是函数,虽然静态方法定义在类中,但是静态方法并不是类或者类实例的方法,而可以理解为与类没有直接关系的函数,那么静态方法定义在类中的意义是因为可以将一些功能性的工具函数放在类中,方便调用。
示例
1 | class Foo(object): |
特殊成员方法(魔术方法)
常用魔术方法
__new__(cls[, …])
:
python3中在类实例化过程中首先要调用__new__(cls[, …])
方法,其第一个参数是当前类,其余参数在随后的过程中传递至__init__
方法。
__init__(self[, …])
:
可以理解为python中的构造方法,当一个实例被创建时进行初始化的方法。
__del__(self)
:
python中的析构方法,当实例被销毁时调用该方法,可以执行清理相关功能。
__call__(self[, args…])
:
允许一个类的实例像函数一样被调用:foo(x, y) 调用 foo.__ call__(x, y)
__len__(self)
:
调用len() 时的操作
__repr__(self)
:
调用repr() 时的操作
__str__(self)
:
调用str() 时的操作
__bytes__(self)
:
调用bytes() 时的操作
__hash__(self)
:
调用hash() 时的操作
__bool__(self)
:
调用bool() 时的操作,返回True或False
__format__(self, format_spec)
:
调用format() 时的操作
属性相关
__getattr__(self, name)
:
当尝试获取不存在的属性时的操作
__getattribute__(self, name)
:
当前类的属性被访问时的操作
__setattr__(self, name, value)
:
定义当一个属性被设置时的行为
__delattr__(self, name)
:
当属性被删除时的操作
__dir__(self)
:
调用dir()时的操作
__get__(self, instance, owner)
:
当获得描述符的值时的操作
__set__(self, instance, value)
:
当修改描述符的值时的操作
__delete__(self, instance)
:
当删除描述符的值时的操作
比较操作符
__lt__(self, other)
:
调用小于号时的操作:即x < y 调用 x.lt(y)__le__(self, other)
:
调用小于等于号时的操作:即x <= y 调用 x.le(y)__eq__(self, other)
:
调用等于号时的操作:即x == y 调用 x.eq(y)__ne__(self, other)
:
调用不等于号时的操作:即x != y 调用 x.ne(y)__gt__(self, other)
:
调用大于号时的操作:即x > y 调用 x.gt(y)__ge__(self, other)
:
调用大于等于号时的操作:即x >= y 调用 x.ge(y)
算数运算符 & 反运算
反运算:即当左操作数不存在对应方法时,则检查右操作数是否有相对应的反运算符,若有则进行对应运算,若没有则抛出异常
__radd/add__(self, other)
:
调用加法时的操作:+
__rsub/sub__(self, other)
:
调用减法时的操作:-
__rmul/mul__(self, other)
:
调用乘法时的操作:*
__rtruediv/truediv__(self, other)
:
调用除法时的操作:/
__rfloordiv/floordiv__(self, other)
:
调用整除时的操作://
__rmod/mod__(self, other)
:
调用取模运算时的操作:%
__rdivmod/divmod__(self, other)
:
调用 divmod() 时的操作
__rpow/pow__(self, other[, modulo])
:
调用 power() 或 **
时的操作
__rlshift/lshift__(self, other)
:
调用按位左移时的操作:<<
__rrshift/rshift__(self, other)
:
调用按位右移时的操作:>>
__rand/and__(self, other)
:
调用按位与时的操作:&
__rxor/xor__(self, other)
:
调用按位异或时的操作:^
__ror/or__(self, other)
:
调用按位或时的操作:|
增量赋值运算
上述算数运算符前增加i
,则转换为对应的增量赋值运算符,对应操作转换为赋值运算
例如:__iadd__(self, other)
,则调用赋值加法时的操作,即+=
一元操作符
__pos__(self)
:
调用正号时的操作
__neg__(self)
:
调用负号时的操作
__abs__(self)
:
调用 abs() 时的操作
__invert__(self)
:
调用按位求反时的操作
类型转化
__complex__(self)
:
调用 complex() 时的操作
__int__(self)
:
调用 int() 时的操作
__float__(self)
:
调用 float() 时的操作
__round__(self[, n])
:
调用 round() 时的操作
__index__(self)
:
调用此方法以实现 operator.index() 以及 Python 需要无损地将数字对象转换为整数对象的场合(例如切片或是内置的 bin(), hex() 和 oct() 函数)。存在此方法表明数字对象属于整数类型。必须返回一个整数。
上下文管理
__enter__(self)
:
当使用 with 语句时,返回值被 with 语句的目标或者 as 后的名字绑定。
__exit__(self, exc_type, exc_value, traceback)
:
退出关联到此对象的运行时上下文。通常用于处理异常、清除处理或做一些代码块执行完毕之后的日常工作。
容器类型
__len__(self)
:
调用 len() 时的操作
__getitem__(self, key)
:
获取容器中元素时的操作: self[key]
__setitem__(self, key, value)
:
设置容器中元素时的操作: self[key] = value
__delitem__(self, key)
:
删除容器中元素时的操作: del self[key]
__iter__(self)
:
对容器中元素进行迭代时的操作
__reversed__(self)
:
被 reversed() 调用时的操作
__contains__(self, item)
:
调用 in 时的操作
__slots__
概念
__slots__
允许我们显式地声明数据成员并禁止创建__dict__
和__weakref__
(除非是在 slots 中显式地声明或是在父类中可用。)意义及作用
相比使用 dict 此方式可以显著地节省空间。
属性查找速度也可得到显著的提升。
__slots__
不可被继承,也不可动态添加属性示例
1 | class Foo: |
反射(自省)
概念
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
python中的反射
通过字符串的形式操作对象相关的属性,python中的一切事物都是对象(都可以使用反射)。
反射的实现
hasattr(obj, name)
返回obj对象是否具有name所描述的属性getattr(obj, name)
从obj对象中获取到name所描述的属性setattr(obj, name, value)
给obj对象设置一个名为name的属性,属性值为valuedelattr(obj, name)
从obj对象中删除名为name的属性
示例
1 | # 反射示例中的属性和方法 |