类似__xx,以双下划线开头的实例变量名,就变成了一个私有变量(private),只有内部可以访问,外部不能访问;双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量
类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如__author__、__name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”
特殊变量
__doc__: 定义文档字符串__dict__: 类的属性列表__class____slots__: 对类的实例可以动态的绑定属性和方法__init__: 创建实例的时候,可以调用__init__方法做一些初始化的工作。与普通的实例方法类似,如果子类不重写__init__,实例化子类时,会自动调用父类的__init__;如果子类重写了__init__,实例化子类时,则只会调用子类的__init__,此时如果想使用父类的__init__,可以使用super函数__new__:__init__是实例创建之后调用的第一个方法,而__new__更像构造函数,它在__init__之前被调用。另外,__new__方法是一个静态方法,第一参数是cls,__new__方法必须返回创建出来的实例。__del__: 类似析构函数。【析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数】__enter__: 这个方法是用于支持with语句的上下文管理器。__exit__: 这个方法是用于支持with语句的上下文管理器。__iter__: 如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。__call__: 实例可以像函数一样调用__str__: 返回用户看到的字符串__repr__: 返回开发者看到的字符串(用于调试)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# test.py
class P(object):
def __str__(self):
return "__str__ called"
def __repr__(self):
return "__repr__ called"
p = P()
>>> from test import p
>>> p
__repr__ called
>>> print p
__str__ called__getitem__: 支持下标(或切片)操作的函数__setitem__: 支持下标(或切片)操作的函数__delitem__: 支持下标(或切片)操作的函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class Fib(object):
def __getitem__(self, n):
if isinstance(n, int):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice):
start = n.start
stop = n.stop
a, b = 1, 1
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L
fib = Fib()
print fib[10]
print fib[0:10]__getattr__: 支持点操作(即 “对象.属性” 访问方式)。当访问不存在的属性时,才会使用__getattr__方法__getattribute__: 支持点操作(即 “对象.属性” 访问方式)。当每次调用属性时,python会无条件进入__getattribute__中,不论属性存在与否,这就是与__getattr__的区别__setattr__: 支持点操作(即 “对象.属性” 访问方式)__delattr__: 支持点操作(即 “对象.属性” 访问方式)