python 魔法方法

I am not a creator, I just a porter.

Note: Everything is object in python. 对于Python来说一切都是对象,也就是函数的参数可以传递任何你想传递的参数。在Python中整数,浮点都是对象,函数,类也是对象。这一点和Java有点不同,在Java中是有基本类型的所以有装箱拆箱。但在Python中都是对象,所以万物皆对象!

>>> dir(1)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> type(1)
<type 'int'>

python对象的特殊方法 ### {#method}


构造方法

  • __new__(cls, *args, **kwargs)

    __new__ 是对象实例化时第一个调用的方法,它取下cls并把它传递给__init__。注意,在继承的过程中,是先调用父类的__new__在调用本类的__init__。在使用过程中,常用来根据特定的条件来构造类,也是实现单例模式的一个技巧。
  • __init__(cls, *args, **kwargs)

    __init__是类的初始化方法,可以获取任何传入构造器的参数。
  • __del__(cls, *args, **kwargs)

    __del__是对象的销毁器。它并非实现了语句del x(因此该语句不等同于 x.__del__()),而是定义了当对象被垃圾回收是的行为。

这是一个简单实现单例模式的例子:

class Singleton(object):
""" 单例模式 """
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = super(cls, Singleton).__new__(cls)
return cls._instance

访问控制

  • __getattr__(self, name)

    当用户试图访问一个根本不存在(或者暂时不存在)的属性时,可以通过这个魔法方法定义类的行为。这个可以用于使用废弃属性时给出警告。。。。
  • __setattr__(self, name, value)

    这个是用来定义属性的赋值行为,不管这个属性存在与否,可以对任意的属性的任何变化定义自己的规则,要小心使用。
  • ___detattr__(self, name)

    这个是用于处理删除属性行为,当我们del self.name时调用,注意防止无限递归。
  • __getattribute__(self, name)

    这个定义属性(不管存在不存在)被访问时的行为,用于新式类。也容易出现无限递归。产生AttributeError

无限递归的问题:

def __setattr__(self, name. value):
self.name = value
# 因为每次属性幅值都要调用 __setattr__(),所以这里的实现会导致递归
# 这里的调用实际上是 self.__setattr('name', value)。因为这个方法一直
# 在调用自己,因此递归将持续进行,直到程序崩溃 def __setattr__(self, name, value):
self.__dict__[name] = value # 使用 __dict__ 进行赋值
# 定义自定义行为

自定义序列

  • __len__(self)

    定义内建len()的行为
  • __getitem__(self, key)

    定义对容器使用self[key]进行读取操作的行为,产生KeyError或TypeError
  • __setitem__(self, key, value)

    定义对容器使用self[key] = value进行赋值的行为,产生KeyError或TypeError
  • __iter__(self)

    用于内建iter(),返回一个可迭代对象
  • __next__(self)

    python 3才有,python2中是next,迭代访问对象,
  • __reversed__(self)

    定义内建reversed()的行为
  • __contains__(self, item)

    定义in,not in的行为
  • __missing__(self, key)

    定义试图访问一个字典中不存在的键时的行为

可调用的方法

  • __call__(self, *args, **kwargs)

    允许类实例像函数那样被调用

上下文管理器

  • __enter__(self)

    定义使用with声明创建的语句块最开始应该做什么,它的返回值会赋值给with声明的目标,也就是as之后的东西
  • __exit__(self, exception_type, exception_value, traceback)

    定义当with声明的语句块执行完毕时,上下文管理器的行为

描述器

当一个类含有 __get__,__set__, __delete__中的一个时,就称它为描述器。

  • __get__(self, instance, type)

    定义当试图取出描述符的值时的行为。 instance 是拥有者类的实例, type是拥有者类本身。
  • __set__(self, instance, value)

    定义当描述符的值改变时的行为。 instance 是拥有者类的实例, value 是要赋给描述符的值。
  • __delete__(self, instance)

    定义当描述符的值被删除时的行为。 instance 是拥有者类的实例

这是property()一个纯Python的等价实现:

class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c" def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError, "unreadable attribute"
return self.fget(obj) def __set__(self, obj, value):
if self.fset is None:
raise AttributeError, "can't set attribute"
self.fset(obj, value) def __delete__(self, obj):
if self.fdel is None:
raise AttributeError, "can't delete attribute"
self.fdel(obj) class Cell(object): def getvalue(self, obj):
"Recalculate cell before returning value"
self.recalc()
return obj._value value = Property(getvalue)

类的表示

  • __str__(self)

    定义内建str()的行为
  • __repr__(self)

    定义内建repr()的行为。str()产生人可读的输出,repr()产生机器可读的输出
  • __unicode__(self)

    定义内建unicode()的行为
  • __format__(self)

    用于新式字符串格式化时的行为
  • __hash__(self)

    用于内建hash()的行为,实现这个方法通常也实现__eq__,使得 a == b意味着hash(a) == hash(b)
  • __dir__(self)

    定义内建dir()的行为
  • __nonzero__(self)

    定义内建bool()的行为

操作符

  • __cmp__(self, other)

    定义所以比较操作符的行为,self == other时返回0,self > other时返回正整数,self < other时返回负整数。
  • __eq__(self, other)

    定义操作符(==)的行为
  • __ne__(self, other)

    定义操作符(!=)的行为
  • __lt__(self, other)

    定义操作符(<)的行为
  • __gt__(self, other)

    定义操作符(>)的行为
  • __le__(self, other)

    定义操作符(<=)的行为
  • __ge__(self, other)

    定义操作符(>=)的行为
  • __pos__(self)

    定义操作符(+)的行为,取正操作:+some_object
  • __neg__(self)

    定义操作符(-)的行为,取负操作:-some_object
  • __abs__(self)

    定义内嵌函数abs()的行为
  • __invert__(self)

    定义取反操作符(~)的行为
  • __round__(self, n)

    定义内嵌函数round()的行为,n为近视小数点的位数
  • __floor__(self)

    定义math.floor()的行为,向下取整
  • __ceil__(self)

    定义math.ceil()的行为,向上取整
  • __add__(self, other)

    定义加法操作符(+)的行为
  • __sub__(self, other)

    定义减法操作符(-)的行为
  • __mul__(self, other)

    定义乘法操作符(*)的行为
  • __floordiv__(self, other)

    定义除法操作符(//)的行为
  • __div__(self, other)

    定义除法操作符(/)的行为
  • __mod__(self, other)

    定义取宇操作符(%)的行为
  • __divmod__(self, other)

    定义内建divmod()的行为
  • __pow__(self)

    定义操作符(**)的行为
  • __lshift__(self, other)

    定义左移操作符(<<)的行为
  • __rshift__(self, other)

    定义右移操作符(>>)的行为
  • __and__(self, other)

    定义按位与操作符(&)的行为
  • __or__(self, other)

    定义按位或操作符(|)的行为
  • __xor__(self, other)

    定义按位异或操作符(^)的行为

注1:反射算数运算符,所谓的反射运算只不过是运算符交换了以下位置:self + other变成other + self。反射运算符的定义就是在原运算符的前面加个r,如__add__对应的反射运算符就是__radd__。

注2:增强赋值运算符(+=, -=, ...),定义就是在原运算符前面加一个i,如__add__对应的就是__iadd__。

类型转换

  • __int__(self)

    实现到int的类型转换
  • __long__(self)

    实现到long的类型转换
  • __float__(self)

    实现到float的类型转换
  • __complex__(self)

    实现到complex的类型转换
  • __oct__(self)

    实现到八进制数的类型转换
  • __hex__(self)

    实现到十六进制数的类型转换
  • __index__(self)

    实现当对象应用于切片表达式时到一个整数的类型转换
  • __coerce__(self, other)

    实现混合模式算数运算,如果不能进行类型转换,返回None,反之返回一个二元组self和other,这两者都被转换为相同的类型
上一篇:IO编程


下一篇:Initializing Spring root WebApplicationContext