###1. Class Objects
When a class definition is entered, a new namespace is created, and used as the local scope — thus, all assignments to local variables go into this new namespace. In particular, function definitions bind the name of the new function here.
特别回顾上一篇的命名空间,class的定义开辟新的命名空间,该空间为local scope
,但是从module的角度来看,class的name属于该module的global namespaces
。该结论并没有出处,是笔者自己的理解。
>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
官网给出的例子,然后配合下面的说明理解class的定义:
- Class objects support two kinds of operations: attribute references and instantiation.
属性引用或者实例化
- Attribute references use the standard syntax used for all attribute references in Python: obj.name. Valid attribute names are all the names that were in the class’s namespace when the class object was created.
有效的属性名字必须属于class对象的命名空间
- Class attributes can also be assigned to, _doc_ is also a valid attribute, returning the docstring belonging to the class.
class属性可以被赋值
- Class instantiation uses function notation. Just pretend that the class object is a parameterless function that returns a new instance of the class.
- a class may define a special method named _init_(), class instantiation automatically invokes _init_() for the newly-created class instance.
实例化的时候自动调用_init_()
- Of course, the _init_() method may have arguments for greater flexibility. In that case, arguments given to the class instantiation operator are passed on to _init_().
实例化时传递的参数最终给_init_
2. Instance Objects
- Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to.
class的数据属性并不需要在class的定义中声明,如下小实验验证:
>>> class change:
... def sum(self):
... z=1
... i=1
...
>>> x=change()
>>> x.j=2
>>> x.j
2
>>>
- The other kind of instance attribute reference is a method.
- Valid method names of an instance object depend on its class. By definition, all attributes of a class that are function objects define corresponding methods of its instances.
实例化之后,原来的函数对象变成该实例的method对象,两者是有区别的
3. Method Objects
- In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s instance object before the first argument.
x.sum()和change.sum(x)效果一样,理解这个需要理解深刻理解一切东西都是对象的含义
- If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters. When an instance attribute is referenced that isn’t a data attribute, its class is searched. If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object.
method object生成的过程
- When the method object is called with an argument list, a new argument list is constructed from the instance object and the argument list, and the function object is called with this new argument list.
比较复杂的陈述了这个method调用的过程,该部分进一步解释上面x.sum()=change.sum(x)
4. Class and Instance Variables
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
官网给的例子上的注释很清楚的解释了什么是Class and Instance Variables
,然后又给出下面的例子:
class Dog:
tricks = [] # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks # unexpectedly shared by all dogs
['roll over', 'play dead']
如果从namespace思考的话,所有实例共享class Dog的命名空间,其trick
被所有实例共享,而name
只有实例自己可以访问,如果改动代码如下:
>>> class Dog:
name = 'a'
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
>>> x=Dog('b')
>>> x.name
'b'
>>>
如果应用namespaces的规则,那么name
首先在local scope
查找,所以x.name=b
而不是a
。
5. 总结
从内容编排来看介绍了Class Objects, Instance Objects, Method Objects
,特别强调了object
,最后又给出了Class and Instance Variables
,该特性在之后的private
详细讨论。总之理解上一篇的命名空间是基础,之后才能更深的理解其他概念,目前笔者感觉用The Python Tutorial
入门是错误的决定。