由于是一种脚本语言, python的类仅仅是在脚本语言的基础上进行的一定的封装
1, 类定义中的表达式会在代码第一次被引用时执行(脚本的模式)
>>> class A():... print "expression in the calss defination"
... a=1
... b=2
... def f(self):
... print "execution of the function"
...
expression in the calss defination
>>> a1 = A()
>>> a2 = A()
>>>
在上例中, "a=1", "b=2"都会在解释器分析到相应的行时执行一次.
2, 类变量
类变量的声明及相当于在类名的命名空间新定义了一个新的命名映射
class A():
a = 1
相当于:
A.a = 1
与给module A 中的变量a赋值为1类似
3, 成员变量
成员变量的声明相当于在实例的命名空间内加入了一个新的命名映射
>>> class A():
... pass
...
>>> var = A()
>>> var.a = 1
4, 类的实例化
类的实例化实际上只是复制了类的所有属性给新的实例名
>>> class A():
... a = 1
... def __init__(self):
... self.b = 1
... def func(self):
... print "test"
...
>>> id(A.a)
10416224
>>> id(A.func)
11509032
>>> type(A.a)
<type 'int'>
>>> type(A.func)
<type 'instancemethod'>
>>> v = A()
>>> id(v.a)
10416224
>>> id(v.func)
11509032
>>> type(v.a)
<type 'int'>
>>> type(v.func)
<type 'instancemethod'>
>>>
由上边的例子可以看出, 实例话v的过程实际上就是吧A的所有属性(成员, 方法)都
复制给了v一份.此处的复制是指名字的复制而不是指内存内容的复制. 即实例具有了
和类一样的成员名字, 且指向相同的内存地址.
在复制过程结束后, 构造函数会被执行, 如下例:
>>> class A():
... a = 1
... def __init__(self):
... print "self.a = %s" % self.a
... self.b = 1
...
>>> a1=A()
self.a = 1
当构造函数执行时, 已经可以引用复制过来的类的变量
5, 成员方法的调用
当试图调用一个成员方法时, 解释器会将类的实例默认作为第一个
参数传递给此方法.
a = A()
a.func() <==> A.func(a)
有下边的例子可以看出, 虽然类方法和成员方法指向相同的内存地址,
但是成员方法是"bound"的, 即调用时解释器会自动传入第一个参数
>>> class A():... def func(self):
... print "test"
...
>>> v=A()
>>> id(v.func)
11613528
>>> id(A.func)
11613528
>>> v.func
<bound method A.func of <__main__.A instance at 0x00BC01C0>>
>>> A.func
<unbound method A.func>