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

Python对象常见的特殊属性

1. C.__name__

  对象的名称,比如类型(type, class)对象的名称就是系统内置的或自定义的名称字符串,类型的实例通常没有属性 __name__。

>>> class A(object):
... pass
...
>>> a = A()
>>> A.__name__
'A'
>>> a.__name__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute '__name__'
>>> list.__name__
'list'

2. C.__bases__

  元组,包含 类型对象(type, class) C 的全部基类,类型的实例通常没有属性 __bases__。

>>> class A(object): pass
>>> class B(A): pass
>>> class C(A): pass
>>> class D(B, C): pass
>>> D.__bases__
(<class '__main__.B'>, <class '__main__.C'>)

3. x.__class__

   Python对象,是实例或类型 x 所属的类型,其值等于 type(x)

>>> d = D()
>>> d.__class__
<class '__main__.D'>
>>> D.__class__
<type 'type'>

  

4. x.__dict__

  字典,除了一些特殊的属性,实例、类型等对象的所有属性,都放置在其 __dict__ 字典中。

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 。

  *区别 __getattribute__ 和 __getattr__,前者是任何通过 x.y 访问实例的属性时都会调用的特殊方法,而后者则是在正常访问形式下无法找到的情况下才会被调用。

__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)容器才应该定义该方法。

内置object类型的特殊方法

  object 类型是所有内置和自定义类型的祖先,它定义了一些基本的特殊方法,这些方法的含义在前文已经介绍过:

__new__

__init__

__delattr__

__getattribute__

__setattr__

__hash__

__repr__

__str__

静态方法(Static Method)

  静态方法是指:

  • 尽管定义和使用上和普通的函数完全相同,但通常要在某个类型中定义,;
  • 通过 类型 和 实例 都能调用;
  • 定义静态方法时不用额外指定第一个参数,Python也不会隐式地传递任何内容作为第一个参数;
  • 使用装饰器 @staticmethod 来定义静态方法;

例如:

>>> class A(object):
... @staticmethod
... def f(x, y): return x + y
...
>>> A.f(1, 9)
10
>>> a = A()
>>> a.f(1,9)
10

  静态方法最大的特点就是不需要额外的参数。

类方法(Class Method)

  类方法是指:

  • 定义时的第一个参数为一个类型 cls ,调用类方法时Python自动地将调用该方法的类型(或者调用该方法的实例所属的类型)传递给类方法的首个参数;
  • 通过 类型 和 实例 都能够调用;
  • 使用装饰器 @classmethod 定义类方法

例如:

>>> class A(object):
... @classmethod
... def f(cls, x):
... print 'class name: %s.' % cls.__name__
... print 'the argument you passed in: %s.' %x
...
>>> A.f('hello')
class name: A.
the argument you passed in: hello.
>>> a = A()
>>> a.f('world')
class name: A.
the argument you passed in: world.

  类方法的最大特点是定义时的第一个参数代表调用该方法的类型或实例所属的类型,而Python会隐式地将这个类型对象传给类方法。

  静态方法和类方法都是类级方法,不同于实例方法。

Python——特殊属性与方法的更多相关文章

  1. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  2. python动态绑定属性和方法

    基于Python 2.7.13测试. Python是动态语言,在类定义了之后,还可以动态地绑定属性和方法. 下面先来看怎么给类的实例动态地绑定属性和方法. >>> class Stu ...

  3. Python 类属性和方法

    import types class Dog(object): __slots__ = ("name", "color", "info") ...

  4. 菜鸟初识python request属性及方法说明

    if  request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属性 描述 path 表示提交请求页面完 ...

  5. python request属性及方法说明

    if  request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属      性 描述 path 表示提 ...

  6. 转:python request属性及方法说明

    转:http://blog.csdn.net/u013398398/article/details/52214582 if  request.REQUEST.has_key('键值'): HttpRe ...

  7. Python复数属性和方法操作实例

    转自: https://blog.csdn.net/henni_719/article/details/56665254 #coding=utf8 ''' 复数是由一个实数和一个虚数组合构成,表示为: ...

  8. python常用函数和方法 - 备忘

    语法语句篇 除法运算(精确运算和截断运算) 在python2中,除法运算通常是截断除法.什么是截断除法: >>> 3/4 0 # 自动忽略小数项 要是想 得到正确结果 怎么办呢? m ...

  9. python动态获取对象的属性和方法 (转载)

    首先通过一个例子来看一下本文中可能用到的对象和相关概念. #coding:utf-8 import sys def foo():pass class Cat(object): def __init__ ...

随机推荐

  1. Python3NumPy——ndarray对象

    Python3NumPy——ndarray对象 1.前沿 推荐导入语法:import numpy as np NumPy中使用ndarray对象表示数组,ndarray是NumPy库的核心对象 2.创 ...

  2. 潭州课堂25班:Ph201805201 第十四课 异常,处理 (课堂笔记)

    程序难免会出现错误 : 语法错误 : 逻辑错误: AttributeError  -->>  试图访问一个对象没有的属性, IOError  ---->>  输入输出异常 In ...

  3. 用一颗学美术的心来理解PID调节

    用一颗学美术的心来理解PID调节 泡利 3 个月前 相信大家小时候都画过美术作品吧?(什么?你还是宝宝?)没关系,不管你是文科.理科.工科.艺术还是家里蹲的,这篇文章对你来说一定会简单到爆炸的. 这种 ...

  4. js监听全屏的事件

    window.addEventListener('click',function(){ window.top.location.href = '../../loginOut.do';  //解决ifr ...

  5. angularJS常用的内置方法

    angular.lowercase(aaa); angular.uppercase(bbb); angular.isString(); angular.isNumber(); angular.isAr ...

  6. json数据格式 net.sf.json.JSONException: A JSONObject text must begin with '{' at character 1 of Error:(findColumns1)Read timed out

    substring(3)的用法http://www.w3school.com.cn/jsref/jsref_substring.asp 可能一:sb是要转化的数据,以sb是String为例       ...

  7. oracle case when 用法

    原文:http://www.cnblogs.com/eshizhan/archive/2012/04/06/2435493.html 1. CASE WHEN 表达式有两种形式 --简单Case函数 ...

  8. JDBC(3)—ResultSet结果集

    简介:ResultSet:结果集.封装了使用JDBC进行查询的结果.Statement只能进行更新操作,所以使用ResultSet进行查询操作. 1.调用Statement对象的executeQuer ...

  9. HDU4655【题意+分析】

    哎这题有点意思.. 一开始肿么看都不理解题意,发现好多ACM题都这样,好多英文意思不能完全理解,只得照样例猜啦,猜不出来?? 那就靠神队友解释了,囧. 就是排列,涂色使结果最大化. 反正别人的博客把这 ...

  10. python 环境搭建和Spyder的安装应用

    http://blog.csdn.net/BurneAris/article/details/75214976