Python——特殊方法

  Python中以双下划线开头和结尾的函数称为特殊函数,对于实例执行一些特定的运算时,Python会自动视图调用这些实例的特殊方法,从而在Python中可以很轻易地实现运算符的重载。

  Python中有一些通用的特殊函数:

1. 初始化与终止化

__new__(cls[, args...])

  __new__()是一个静态方法,用于根据类型创建实例。Python在调用__new__()方法获得实例后,会调用这个实例的__init__()方法,然后将最初传给__new__()方法的参数都传给__init__()方法。

__init__()

  __init__()是一个实例方法,用来在实例创建完成后进行必要的初始化,该方法必须返回None.

  Python不会自动调用父类的__init__()方法,这需要额外的调用:

super(C, self).__init__()

来完成。

__del__(self)

  在GC之前,Python会调用这个对象的__del__()方法完成一些终止化工作。如果没有__del__()方法,那么Python不做特殊的处理;

  Python无视__del__()方法的返回值;

  Python不会自动调用父类的__del__()方法,除非显式调用;

  定义了__del__()方法的实例无法参与到循环GC中,所以对于这样的实例应该避免循环引用;

  try/finally语句或with语句可能是比__del__()更好的方式。

2. 表现形式

__repr__(self)

  Python内置的repr()函数,`x`表达式形式,或者交互式解释器在显示一个表达式语句的结果时,都调用这个对象的__repr__()方法;

  __repr__()方法返回的字符串主要是面向解释器的,改写的话应该满足: eval(repr(x)) == x 。

  如果没有定义__repr__(),那么Python使用一种默认的表现形式。

__str__(self)

  Python内置的1. str()函数,2. print(x)语句,都会调用对象的__str__()方法;

  与__repr__()返回的详尽的、准确的、无歧义的对象描述字符串不同,__str__()方法只是返回一个对应对象的简洁的字符串表达形式;

  当__str__()缺失时,Python会调用__repr__()方法;

  __str__()返回的字符串应该是面向用户的,可读的。

__unicode__(self)

  Python内置的unicode(x)方法会调用__unicode__()方法;

  该方法如果定义,优先级高于__str__()方法;

  同时定义这两个方法的实例,调用它们的结果应该相同。

3. 比较、哈希与布尔值

__lt__(self, other)

  x<y 运算将会调用实例x的__lt__(self, other)方法;

__le__(self, other)

  x<=y 运算将会调用实例x的__le__(self, other)方法;

__gt__(self, other)

  x>y 运算将会调用实例x的__gt__(self, other)方法;

__ge__(self, other)

  x>=y 运算将会调用实例x的__ge__(self, other)方法;

__eq__(self, other)

  x==y 运算将会调用实例x的__eq__(self, other)方法;

__ne__(self, other)

  x!=y 运算将会调用实例x的__ne__(self, other)方法;

  *上述用于实例间比较的特殊方法应该返回True或False,或者返回NotImplemented来告诉Python解释器使用其他的方式进行比较。

__cmp__(self, other)

  对于上面提到的比较操作,如果对应的特殊方法没有定义或者返回NotImplemented,则会调用__cmp__(self, other)再进行一次尝试;

  一些内置的方法:cmp(x, y), max(x, y)或者列表对象的sort()方法也会调用__cmp__()方法;

  实现x.__cmp__()方法时,如果x小于y,应该返回-1,如果x大于y,应该返回1;如果x等于y,应该返回0.

  对于序列化比较(<, <=, >=, >),如果最终__cmp__()也没有定义,那么会抛出异常;

  对于相等与否的比较(==, !=),如果最终__cmp__()也没有定义,将会变成身份检验:判断id(x) == id(y)是否成立。

__hash__(self)

  三种情形会调用__hash__()方法:1. 内置的hash()方法,2.作为字典的键时,3.作为集合的成员时;

  __hash__()方法应该返回一个32位长的整数,对与同一个对象,__hash__()方法应该总是返回相同的值;对于 x == y ,即使二者不属于相同的类型,只要他们是可哈希的(hashable),都应该确保得到 hash(x) == hash(y) ;

  没有 __hash__() 方法,也没有 __cmp__() 和 __eq__() 方法,上面提到的三种情形将使用id(x)作为替代;

  没有 __hash__() 方法,但是有 __cmp__() 和 __eq__() 方法,上面提到的前两种方法会抛出异常;

  通常只为同时定义了 __cmp__()和/或__eq__() 方法的不可变(immutable)对象定义__hash__()方法,

  

__nonzero__(self)

  判断一个对象是为真还是假时,例如调用bool(x)方法时,Python会调用x.__nonzero__(self)方法,__nonzero__()方法应该返回True或False。

  如果实例没有__nonzero__()方法,那么Python会调用实例的__len__()方法,当__len__()方法返回0时,Python认为该对象为假。所以如果实例没有__nonzero__()方法与__len__()方法,则Python认为该实例总是真的;

  *所以以一个容器是否非空为判断条件时,应该写成:

if container:
  pass

而不是:

if len(container) > 0 :
  pass

因为后者将错过__nonzero__()方法的检验。

4. 属性的引用、绑定与解绑定

__getattribute__(self, name)

  访问对象的属性x.y时,Python会自动调用 x.__getattribute__(‘y‘) 方法;

  __getattribute__()方法应该返回被访问的属性的值或者是抛出异常 AttributeError ;

  覆写类型的__getattribute__()方法会导致实例的属性访问变慢。

__getattr__(self, name)

  当常规的属性访问( x.__class__ 或 x.__dict__ 的键访问)无法找到目标属性时,Python会调用 __getattr__() 方法;

  如果该方法没能找到目标属性,应该抛出 AttributeError 。

__setattr__(self, name, value)

  绑定实例的某个属性(赋值),例如 x.y = value 时,Python会自动调用 x.__setattr__(‘y‘, value) 方法;

  Python无视 __setattr__() 方法的返回值;

  如果没有定义 __setattr__() 方法,Python将赋值 x.y = value 解释成 x.__dict__[‘y‘] = value 。

__delattr__(self, name)

  当解绑定一个对象的某个属性(例如调用 del x.y )时,会调用 x.__delattr__(‘y‘) 方法;

  Python无视__delattr__()方法的返回值;

  如果没有定义__delattr__()方法,那么Python将 del x.y 解释成 del x.__dict__[‘y‘] 。

5. 可调用对象

__call__(self[, args...])

  定义了该方法的对象可以像函数那样被调用,因此被称为可调用对象。

二 、容器的特殊方法

  容器可以是 序列(sequence) 或者 映射(mapping)

__contains__(self, item)

  布尔测试 y in x 会调用 x.__contains__(y) ;

  对于序列x而言,如果y等于x中的某一个值,那么__contains__()方法应该返回True;

  对于映射x而言,如果y等于x的键中的某一个,那么__contains__()方法应该返回True;

  如果没有定义__contains__()方法,那么测试 y in x 等价于:

for z in x:
    if y == z:
        return True
    else:
        return False

__delitem__(self, key)

  从容器中解绑一个项或者切片(如 del x[key] )将会调用 x.__delitem__(key) 方法,

  只有可变对象才应该定义这个方法。

__getitem__(self, key)

  调用 x[key] (索引或切片)时将会调用 x.__getitem__(key) 方法;

__iter__(self)

  对于试图遍历一个容器的全部元素的请求(例如 for i in x ),Python将会调用 x.__iter__() 来获得x上的一个迭代器;

  Python内置函数 iter(x) 也会调用 x.__iter__() 方法;

  如果没有定义__iter__()方法,那么iter(x)方法会合成并返回一个包含x的新的迭代器,然后逐个返回x中的元素;

  最好在每个容器中都实现__iter__()方法。

  

__len__(self)

  Python内置的 len(x) 调用或其他试图得知x中的元素个数的函数都会最终调用 x.__len__() ;

  __len__()方法应该返回整形的数值;

  没有定义__nonzero__()时,Python也会调用__len__()方法来判断容器的真假;

  容器都应该定义__len__()方法,除非实现起来特别昂贵的情形。

  

__setitem__(self, key, value)

  对容器的一个元素或切片进行绑定(如: x[key] = value )时,Python会调用 x.__setitem__(key, value) ;

  可变(mutable)容器才应该定义该方法。

时间: 2024-10-18 04:03:05

Python——特殊方法的相关文章

Python list方法总结

1.向列表的尾部添加一个新的元素 append(...) L.append(object) -- append object to end >>> a = ['sam',24,'shaw'] >>> a.append('35') >>> a ['sam', 24, 'shaw', '35'] 2.查找list中有多少个value count(...) L.count(value) -> integer -- returnnumber of occ

Python capitalize()方法

Python capitalize()方法 capitalize()方法返回字符串的一个副本,只有它的第一个字母大写.对于8位的字符串,这个方法与语言环境相关. 语法 以下是capitalize()方法的语法: str.capitalize() 参数 NA 返回值 此方法返回的字符串只有它的第一个字符大写的副本. 例子 下面的示例演示了capitalize方法的使用. #!/usr/bin/python str = "this is string example....wow!!!";

Python字典方法copy()和deepcopy()的区别

1 from copy import deepcopy # import deepcopy模块 2 d = {} 3 d['name'] = ['black', 'guts'] # d = {'name': ['black', 'guts']} 4 c = d.copy() # c = {'name': ['black', 'guts']} 5 dc = deepcopy(d) # dc = {'name': ['black', 'guts']} 6 d['name'].append('whit

Python strip()方法

描述 Python strip() 方法用于移除字符串头尾指定的字符(默认为空格). 语法 strip()方法语法: str.strip([chars]); 参数 chars -- 移除字符串头尾指定的字符. 返回值 返回移除字符串头尾指定的字符生成的新字符串. 实例 以下实例展示了strip()函数的使用方法: #!/usr/bin/python str = "0000000this is string example....wow!!!0000000"; print str.str

Python startswith()方法

描述 Python startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False.如果参数 beg 和 end 指定值,则在指定范围内检查. 语法 startswith()方法语法: str.startswith(str, beg=0,end=len(string)); 参数 str -- 检测的字符串. strbeg -- 可选参数用于设置字符串检测的起始位置. strend -- 可选参数用于设置字符串检测的结束位置. 返回值 如果检测到

Python 字符串方法详解

Python 字符串方法详解 本文最初发表于赖勇浩(恋花蝶)的博客(http://blog.csdn.net/lanphaday),如蒙转载,敬请保留全文完整,切勿去除本声明和作者信息. 在编程中,几乎90% 以上的代码都是关于整数或字符串操作,所以与整数一样,Python 的字符串实现也使用了许多拿优化技术,使得字符串的性能达到极致.与 C++ 标准库(STL)中的 std::string 不同,python 字符串集合了许多字符串相关的算法,以方法成员的方式提供接口,使用起来非常方便. 字符

Python replace()方法

描述 Python replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次. 语法 replace()方法语法: str.replace(old, new[, max]) 参数 old -- 将被替换的子字符串. new -- 新字符串,用于替换old子字符串. max -- 可选字符串, 替换不超过 max 次 返回值 返回字符串中的 old(旧字符串) 替换成 new(新字符串)后生成的新字符串,如果指定第三个

Python count()方法

描述 Python count() 方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. 语法 count()方法语法: 1 str.count(sub, start= 0,end=len(string)) 参数 sub -- 搜索的子字符串 start -- 字符串开始搜索的位置.默认为第一个字符,第一个字符索引值为0. end -- 字符串中结束搜索的位置.字符中第一个字符的索引为 0.默认为字符串的最后一个位置. 返回值 该方法返回子字符串在字符串中出现的次数.

Python strip()方法介绍

描述 Python strip() 方法用于移除字符串头尾指定的字符(默认为空格). 语法 strip()方法语法: str.strip([chars]); 参数 chars -- 移除字符串头尾指定的字符. 返回值 返回移除字符串头尾指定的字符生成的新字符串. 特别注意:移除的字符串的头尾指定字符,不如不是头尾字符不会移除 例1: >>> a = '     123    '>>> a.strip()'123' 例2: >>> a = '  123

Python str方法总结

1.返回第一个字母大写 S.capitalize(...) S.capitalize() -> string >>>a = 'shaw' >>> b = a.capitalize() >>> print b Shaw 2.按指定长度填充特定字符 center(...) S.center(width[, fillchar]) -> string >>> a = 'linux' >>> print a.cen