《python中的对象,方法,类,实例,函数用法分析》由会员分享,可在线阅读,更多相关《python中的对象,方法,类,实例,函数用法分析(11页珍藏版)》请在金锄头文库上搜索。
1、我真正系统地接触和学习党的基本知识是在这次中级党校的培训班上。通过学习,了解了党的发展历程,对党的性质、宗旨、任务等基本知识有了进一步的了解Python中的对象,方法,类,实例,函数用法分析本文实例分析了Python中的对象,方法,类,实例,函数用法。分享给大家供大家参考。具体分析如下:Python是一个完全面向对象的语言。不仅实例是对象,类,函数,方法也都是对象。复制代码 代码如下:class Foo(object):static_attr = Truedef method(self):passfoo = Foo()这段代码实际上创造了两个对象,Foo和foo。而Foo同时又是一个类,foo
2、是这个类的实例。在C+里类型定义是在编译时完成的,被储存在静态内存里,不能轻易修改。在Python里类型本身是对象,和实例对象一样储存在堆中,对于解释器来说类对象和实例对象没有根本上的区别。在Python中每一个对象都有自己的命名空间。空间内的变量被存储在对象的_dict_里。这样,Foo类有一个_dict_, foo实例也有一个_dict_,但这是两个不同的命名空间。所谓“定义一个类”,实际上就是先生成一个类对象,然后执行一段代码,但把执行这段代码时的本地命名空间设置成类的_dict_. 所以你可以写这样的代码:复制代码 代码如下: class Foo(object):. bar = 1 +
3、 1. qux = bar + 1. print bar: , bar. print qux: , qux. print locals().bar: 2qux: 3qux: 3, _module_: _main_, bar: 2 print Foo.bar, Foo._dict_bar2 2 print Foo.qux, Foo._dict_qux3 3所谓“定义一个函数”,实际上也就是生成一个函数对象。而“定义一个方法”就是生成一个函数对象,并把这个对象放在一个类的_dict_中。下面两种定义方法的形式是等价的:复制代码 代码如下: class Foo(object):. def bar(s
4、elf):. return 2. def qux(self):. return 3. Foo.qux = qux print Foo.bar, Foo._dict_bar print Foo.qux, Foo._dict_qux foo = Foo() foo.bar()2 foo.qux()3而类继承就是简单地定义两个类对象,各自有不同的_dict_:复制代码 代码如下: class Cheese(object):. smell = good. taste = good. class Stilton(Cheese):. smell = bad. print Cheese.smellgood
5、print Cheese.tastegood print Stilton.smellbad print Stilton.tastegood print taste in Cheese._dict_True print taste in Stilton._dict_False复杂的地方在.这个运算符上。对于类来说,Stilton.taste的意思是“在Stilton._dict_中找taste. 如果没找到,到父类Cheese的_dict_里去找,然后到父类的父类,等等。如果一直到object仍没找到,那么扔一个AttributeError.”实例同样有自己的_dict_:复制代码 代码如下:
6、class Cheese(object):. smell = good. taste = good. def _init_(self, weight):. self.weight = weight. def get_weight(self):. return self.weight. class Stilton(Cheese):. smell = bad. stilton = Stilton(100g) print weight in Cheese._dict_False print weight in Stilton._dict_False print weight in stilton._
7、dict_True不管_init_()是在哪儿定义的, stilton._dict_与类的_dict_都无关。Cheese.weight和Stilton.weight都会出错,因为这两个都碰不到实例的命名空间。而stilton.weight的查找顺序是stilton._dict_ = Stilton._dict_ =Cheese._dict_ = object._dict_. 这与Stilton.taste的查找顺序非常相似,仅仅是在最前面多出了一步。方法稍微复杂些。复制代码 代码如下: print Cheese._dict_get_weight print Cheese.get_weight
8、 print stilton.get_weight我们可以看到点运算符把function变成了unbound method. 直接调用类命名空间的函数和点运算返回的未绑定方法会得到不同的错误:复制代码 代码如下: Cheese._dict_get_weight()Traceback (most recent call last):File , line 1, inTypeError: get_weight() takes exactly 1 argument (0 given) Cheese.get_weight()Traceback (most recent call last):File
9、, line 1, inTypeError: unbound method get_weight() must be called with Cheese instance asfirst argument (got nothing instead)但这两个错误说的是一回事,实例方法需要一个实例。所谓“绑定方法”就是简单地在调用方法时把一个实例对象作为第一个参数。下面这些调用方法是等价的:复制代码 代码如下: Cheese._dict_get_weight(stilton)100g Cheese.get_weight(stilton)100g Stilton.get_weight(stilto
10、n)100g stilton.get_weight()100g最后一种也就是平常用的调用方式,stilton.get_weight(),是点运算符的另一种功能,将stilton.get_weight()翻译成stilton.get_weight(stilton).这样,方法调用实际上有两个步骤。首先用属性查找的规则找到get_weight, 然后将这个属性作为函数调用,并把实例对象作为第一参数。这两个步骤间没有联系。比如说你可以这样试:复制代码 代码如下: stilton.weight()Traceback (most recent call last):File , line 1, inTy
11、peError: str object is not callable先查找weight这个属性,然后将weight做为函数调用。但weight是字符串,所以出错。要注意在这里属性查找是从实例开始的:复制代码 代码如下: stilton.get_weight = lambda : 200g stilton.get_weight()200g但是复制代码 代码如下: Stilton.get_weight(stilton)100gStilton.get_weight的查找跳过了实例对象stilton,所以查找到的是没有被覆盖的,在Cheese中定义的方法。getattr(stilton, weigh
12、t)和stilton.weight是等价的。类对象和实例对象没有本质区别,getattr(Cheese, smell)和Cheese.smell同样是等价的。getattr()与点运算符相比,好处是属性名用字符串指定,可以在运行时改变。_getattribute_()是最底层的代码。如果你不重新定义这个方法,object._getattribute_()和type._getattribute_()就是getattr()的具体实现,前者用于实例,后者用以类。换句话说,stilton.weight就是object._getattribute_(stilton, weight). 覆盖这个方法是很容
13、易出错的。比如说点运算符会导致无限递归:复制代码 代码如下:def _getattribute_(self, name):return self._dict_name_getattribute_()中还有其它的细节,比如说descriptor protocol的实现,如果重写很容易搞错。_getattr_()是在_dict_查找没找到的情况下调用的方法。一般来说动态生成属性要用这个,因为_getattr_()不会干涉到其它地方定义的放到_dict_里的属性。复制代码 代码如下: class Cheese(object):. smell = good. taste = good. class Stilton(Cheese):. smell = bad. def _getattr_(self, name):. return Dynamically created attribute %s % name. stilton = Stilton() print sti