24 Python 对象进阶

isinstance(obj,cls)检查是否obj是否是类 cls 的对象

1 class Foo(object):
2      pass
3   
4 obj = Foo()
5   
6 isinstance(obj, Foo)
View Code

issubclass(sub, super)检查sub类是否是 super 类的派生类

1 class Foo(object):
2     pass
3  
4 class Bar(Foo):
5     pass
6  
7 issubclass(Bar, Foo)
View Code

反射

1 什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

 

2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

 1 class Foo:
 2     f = '类的静态变量'
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6 
 7     def say_hi(self):
 8         print('hi,%s'%self.name)
 9 
10 obj=Foo('egon',73)
11 
12 #检测是否含有某属性
13 print(hasattr(obj,'name'))
14 print(hasattr(obj,'say_hi'))
15 
16 #获取属性
17 n=getattr(obj,'name')
18 print(n)
19 func=getattr(obj,'say_hi')
20 func()
21 
22 print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
23 
24 #设置属性
25 setattr(obj,'sb',True)
26 setattr(obj,'show_name',lambda self:self.name+'sb')
27 print(obj.__dict__)
28 print(obj.show_name(obj))
29 
30 #删除属性
31 delattr(obj,'age')
32 delattr(obj,'show_name')
33 delattr(obj,'show_name111')#不存在,则报错
34 
35 print(obj.__dict__)
View Code
 1 class Foo(object):
 2  
 3     staticField = "old boy"
 4  
 5     def __init__(self):
 6         self.name = 'wupeiqi'
 7  
 8     def func(self):
 9         return 'func'
10  
11     @staticmethod
12     def bar():
13         return 'bar'
14  
15 print getattr(Foo, 'staticField')
16 print getattr(Foo, 'func')
17 print getattr(Foo, 'bar')
View Code
 1 import sys
 2 
 3 
 4 def s1():
 5     print 's1'
 6 
 7 
 8 def s2():
 9     print 's2'
10 
11 
12 this_module = sys.modules[__name__]
13 
14 hasattr(this_module, 's1')
15 getattr(this_module, 's2')
View Code

导入其他模块,利用反射查找该模块是否存在某个方法

__str__和__repr__

改变对象的字符串显示__str__,__repr__

自定制格式化字符串__format__

 1 format_dict={
 2     'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
 3     'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
 4     'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
 5 }
 6 class School:
 7     def __init__(self,name,addr,type):
 8         self.name=name
 9         self.addr=addr
10         self.type=type
11 
12     def __repr__(self):
13         return 'School(%s,%s)' %(self.name,self.addr)
14     def __str__(self):
15         return '(%s,%s)' %(self.name,self.addr)
16 
17     def __format__(self, format_spec):
18         # if format_spec
19         if not format_spec or format_spec not in format_dict:
20             format_spec='nat'
21         fmt=format_dict[format_spec]
22         return fmt.format(obj=self)
23 
24 s1=School('oldboy1','北京','私立')
25 print('from repr: ',repr(s1))
26 print('from str: ',str(s1))
27 print(s1)
28 
29 '''
30 str函数或者print函数--->obj.__str__()
31 repr或者交互式解释器--->obj.__repr__()
32 如果__str__没有被定义,那么就会使用__repr__来代替输出
33 注意:这俩方法的返回值必须是字符串,否则抛出异常
34 '''
35 print(format(s1,'nat'))
36 print(format(s1,'tna'))
37 print(format(s1,'tan'))
38 print(format(s1,'asfdasdffd'))
__format__
 1 class B:
 2 
 3      def __str__(self):
 4          return 'str : class B'
 5 
 6      def __repr__(self):
 7          return 'repr : class B'
 8 
 9 
10 b=B()
11 print('%s'%b)
12 print('%r'%b)
%r和%s

__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

1 class Foo:
2 
3     def __del__(self):
4         print('执行我啦')
5 
6 f1=Foo()
7 del f1
8 print('------->')
__del__(析构方法)

item系列

 1 class Foo:
 2     def __init__(self,name):
 3         self.name=name
 4 
 5     def __getitem__(self, item):
 6         print(self.__dict__[item])
 7 
 8     def __setitem__(self, key, value):
 9         self.__dict__[key]=value
10     def __delitem__(self, key):
11         print('del obj[key]时,我执行')
12         self.__dict__.pop(key)
13     def __delattr__(self, item):
14         print('del obj.key时,我执行')
15         self.__dict__.pop(item)
16 
17 f1=Foo('sb')
18 f1['age']=18
19 f1['age1']=19
20 del f1.age1
21 del f1['age']
22 f1['name']='alex'
23 print(f1.__dict__)
__getitem__/__setitem__/__delitem__

__new__

1 class Foo:
2     def __init__(self):
3         self.x = 1
4         print('in init function')
5 
6     def __new__(cls, *args, **kwargs):
7         print('in new function')
8         return object.__new__(cls, *args, **kwargs)
__new__

__call__

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

 1 class Foo:
 2 
 3     def __init__(self):
 4         pass
 5     
 6     def __call__(self, *args, **kwargs):
 7 
 8         print('__call__')
 9 
10 
11 obj = Foo() # 执行 __init__
12 obj()       # 执行 __call__
__call__

__len__

 1 class Foo:
 2     def __init__(self):
 3         self.a = 1
 4         self.b = 2
 5 
 6     def __len__(self):
 7         return len(self.__dict__)
 8 
 9 f = Foo()
10 print(len(f))
__len__

__hash__

 1 class Foo:
 2     def __init__(self):
 3         self.a = 1234
 4         self.b = 5678
 5 
 6     def __hash__(self):
 7         return hash(str(self.a) + str(self.b))
 8 
 9 f = Foo()
10 print(hash(f))
__hash__

__eq__

 1 class Foo:
 2     def __init__(self):
 3         self.a = 1
 4         self.b = 2
 5 
 6     def __eq__(self, other):
 7         if self.a == other.a and self.b == other.b:
 8             return True
 9 
10 a = Foo()
11 b = Foo()
12 print(a == b)
View Code
 1 from collections import namedtuple
 2 Card = namedtuple('Card', ['rank', 'suit'])
 3 class FranchDeck:
 4     ranks = [str(n) for n in range(2,11)] + list('JQKA')
 5     suits = ['红心','方板','梅花','黑桃']
 6 
 7     def __init__(self):
 8         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
 9                                         for suit in FranchDeck.suits]
10 
11     def __len__(self):
12         return len(self._cards)
13 
14     def __getitem__(self, item):
15         return self._cards[item]
16 
17 deck = FranchDeck()
18 print(deck[0])
19 from random import choice
20 print(choice(deck))
21 print(choice(deck))
纸牌游戏1
 1 from collections import namedtuple
 2 Card = namedtuple('Card', ['rank', 'suit'])
 3 class FranchDeck:
 4     ranks = [str(n) for n in range(2,11)] + list('JQKA')
 5     suits = ['红心','方板','梅花','黑桃']
 6 
 7     def __init__(self):
 8         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
 9                                         for suit in FranchDeck.suits]
10 
11     def __len__(self):
12         return len(self._cards)
13 
14     def __getitem__(self, item):
15         return self._cards[item]
16 
17     def __setitem__(self, key, value):
18         self._cards[key] = value
19 
20 deck = FranchDeck()
21 print(deck[0])
22 from random import choice
23 print(choice(deck))
24 print(choice(deck))
25 
26 from random import shuffle
27 shuffle(deck[:52])
28 print(deck[:5])
纸牌游戏2
 1 class Person:
 2     def __init__(self, name, age, sex):
 3         self.name = name
 4         self.age = age
 5         self.sex = sex
 6 
 7     def __hash__(self):
 8         return hash(self.name + self.sex)
 9 
10     def __eq__(self, other):
11         if self.name == other.name or self.sex == other.sex:
12             return True
13 
14 
15 
16 p_lst = []
17 for i in range(84):
18     p_lst.append(Person('egon',i,'male'))
19 
20 print(p_lst)
21 print(set(p_lst))
对象去重

 

posted on 2017-11-25 12:36  潘红伟  阅读(222)  评论(0编辑  收藏  举报

导航