Nigel_Woo

python基础整理笔记(八)

一. python反射的方式来调用方法属性

反射主要指的就是hasattr、getattr、setattr、delattr这四个函数,作用分别是检查是否含有某成员、获取成员、设置成员、删除成员。

此外还有一个 __import__方法,用来与getattr可以实现一些根据字符串来动态的获取模块、方法、属性的方法,示例如下:

 1 # 普通的import模块方法:
 2 import AA as aa
 3 
 4 # 使用__import__的等效方法:
 5 aa = __import__('AA')
 6 
 7 # 再通过getattr,可以获取到 aa模块里定义的 aaClass
 8 aaClass = getattr(aa, 'aaClass')
 9 # 这样可以正常的实例化
10 aaObj = aaClass ('abc')
11 
12 # 再通过getattr可以把示例里面的方法也用出来,属性也取出来
13 func = getattr(aaObj , 'aaFuncton')
14 func()
15 print(getattr(aaClass, 'aaAttr'))

 

二. python类的一些注意点

1. 定义在子类里的属性和方法(注意不是子类重写的,而是特有的,父类没有的),在父类的方法里面我们也可以调用!但是如果是父类的实例,去调用了使用了这种子类属性的方法,是会报错的!这种实现的作用,是将父类当做类似其他语言中的纯抽象类或者接口的实现,父类里是不会调用这样的方法的,或者实例化父类的。使用这种方式,可以降低代码的重复,将更多的共同抽象到父类里面去。

示例如下:

 1 class Father(object):
 2     def __init__(self):
 3         self.aa = 1
 4         self.bb = 2
 5 
 6     def show_bb(self):
 7         print self.bb
 8 
 9     def show_cc(self):
10         print self.cc
11 
12 
13 class Son(Father):
14     def __init__(self):
15         super(Son, self).__init__()
16         self.cc = 3
17 
18 s1 = Son()
19 s1.show_bb()
20 s1.show_cc()

如图所示,这里调用 show_bb()和show_cc()都是合法的,尽管show_cc()是父类的方法,而且父类没定义cc这个属性。这是因为这里的self是子类自己的s1这个实例。

但是如果要实例化父类并调用show_cc就会出错如下:

 

2. python中类有个特殊的方法 __call__,它的作用是实现了这个方法,那么在调用实例的后面直接加一个(),就会执行这个__call__方法。

示例如下:

 1 class Father(object):
 2     def __init__(self):
 3         self.aa = 1
 4         self.bb = 2
 5 
 6 
 7     def show_bb(self):
 8         print self.bb
 9 
10     def show_cc(self):
11         print self.cc
12 
13 
14 class Son(Father):
15     def __init__(self):
16         super(Son, self).__init__()
17         self.cc = 3
18 
19     def __call__(self, *args, **kwargs):
20         self.show_bb()
21         self.show_cc()
22 
23 s1 = Son()
24 s1()

用这种方法,能够在一些情况下让代码显得更加简洁清晰。

 

3. python中的类,还有个特殊方法__iter__,实现了这个方法,就可以直接对这个类的实例进行迭代,示例如下:

 1 class TestIter(object):
 2     def __init__(self):
 3         self.iter_lst = [1, 3, 4, 5]
 4 
 5     def __iter__(self):
 6         for i in self.iter_lst:
 7             yield  i
 8 
 9 t1 = TestIter()
10 
11 for i in t1:
12     print i

 

4. property, XXX.setter装饰器

在python的类中,还有两个特殊的装饰器,一个叫property,一个叫XXX.setter,

前者作用是能像调用属性一样的调用一个方法,后者作用是能像给属性设值一样调用一个方法...XXX是这个方法的名称。通过这两个装饰器,一个类里面就可以有两个同名的方法,分别负责存取一个像属性的值。

示例如下:

 1 class TestPP(object):
 2     def __init__(self):
 3         self.aa = 1
 4         self.bb = 2
 5 
 6     @property
 7     def aa_bb(self):
 8         return self.load_aa_bb()
 9 
10     @aa_bb.setter
11     def aa_bb(self, new_value):
12         self.save_aa_bb(new_value)
13 
14     @staticmethod
15     def save_aa_bb(aa_bb):
16         with open('aa_bb', 'wb') as fp:
17             fp.write(aa_bb)
18 
19     def load_aa_bb(self):
20         if os.path.exists('aa_bb'):
21             with open('aa_bb', 'rb') as fp:
22                 return fp.read()
23         else:
24             init_value = '%s_%s' % (self.aa, self.bb)
25             self.save_aa_bb(init_value)
26             return init_value
27 
28 pp = TestPP()
29 print(pp.aa_bb)
30 pp.aa_bb = '3333'
31 print(pp.aa_bb)

 这种方式往往用于对一个外部存储的属性(比如存在数据库,json文件中等),进行获取和赋值时候使用,可以使得代码变得简洁。

posted on 2016-07-03 11:00  Nigel_Woo  阅读(161)  评论(0编辑  收藏  举报

导航