对象的属性

首先要理解的是“实例变量”。

我们在__init__方法中并不是创建了实例变量,我们是添加了一个或者多个属性给实际的对象

在__init__内部 self.x = 5和外部 f.x = 5没有什么不同。

 

那么类呢?

1 >>> class Bar(object):
2     pass
3 
4 >>> Bar.foo = 100
5 >>> Bar.foo
6 100
7 >>> Bar
8 <class '__main__.Bar'>

类也是对象,所以它也有属性。但是有一个疑问。我们可以为每一个实例对象定义一个属性通过__init__方法。

那创建一个类的属性,是怎么样的?

答案很简单。函数内部的代码块和类的代码块。函数的内部代码只有当函数触发是才会执行,类的代码块是在类定义好后就执行的,只执行一次

1 >>> class Foo():
2     print("hello")
3 
4     
5 hello
6 >>> 
1 >>> class Foo():
2     x = 100
3 
4     
5 >>> Foo.x
6 100

 

如果我们定义了一个函数,我只是在当前作用域创建了一个变量,如果在类里面定义一个方法,其实是创建了一个新的属性

1 >>> class Foo():
2     def blah(self):
3         return "blash"
4 
5     
6 >>> Foo.blah
7 <unbound method Foo.blash>

 

换句话说,实例的方法在类里面,不在实例对象上,当我们触发f.blah()时,相当于这样f.blah()和Foo.blah(f)

 

如果我触发f.blah(),python怎么知道去触发Foo.blah?  f和Foo是完全两个不同的对象。f是Foo的实例对象,Foo是type的实例对象,python是如何找到Foo的blah属性的呢?

 

python有不同的规则用于变量和属性区域,对于变量,python遵守LEGB规则:本地,闭合,全局,内建。

对于属性,首先它会在对象上寻找,然后再去寻找这个对象的类,然后去寻找这个类的父类。知道寻找到object类

因此f.blah(),先找实例对象f,没有找到属性名blah,去找这个类Foo,在这里找到了然后通过一些方法执行Foo.blah(f)

 

所以python没有实际上的类变量和实例变量之分。有的只是对象的属性。一些事定义在类本身上。一些是建立在类的实例对象上。(当然,类也是type的实例对象,现在往我们忘记它)。这也是为什么一些人认为他们应该定义类上的属性(类变量)。因为它们对实例对象时可见的。

 

最后来看一下代码

 1 >>> class Person():
 2     population = 0
 3     def __init__(self, f, s):
 4         self.f = f
 5         self.s = s
 6         self.population +=1
 7 
 8         
 9 >>> p1 = Person('s','ss')
10 >>> p2 = Person('a', 'aa')
11 >>> p1.population
12 1
13 >>> p1.population
14 1
15 >>> p2.population
16 1
17 >>> Person.population
18 0

 

posted @ 2014-10-18 22:39  pwn_pjy  阅读(249)  评论(0)    收藏  举报