isinstance(obj,cls) 检查是否 obj 是否是类 cls 的对象 返回布尔值
- class Foo(object):
- pass
- obj = Foo()
- isinstance(obj, Foo)
issubclass(sub, super) 检查 sub 类是否是 super 类的派生类 返回布尔值
- class Foo(object):
- pass
- class Bar(Foo):
- pass
- print(issubclass(Bar, Foo)) #object/True
反射? 通过字符串的形式操作对象相关的属性. python 中的一切事物都是对象 (都可以使用反射)
四个可以实现反射的函数:
下面方法适用于类和对象 (一切皆为对象, 类本身也是一个对象)
- # hasattr() 检测存在不
- # getattr() 获取
- # setattr() 设置
- # delattr() 删除
- class Foo:
- f = '类的静态变量'
- def __init__(self,name,age):
- self.name=name
- self.age=age
- def say_hi(self):
- print('hi,%s'%self.name)
- obj=Foo('egon',73) #实例化
- # 检测是否含有某属性
- print(hasattr(obj,'name')) #True
- print(hasattr(obj,'say_hi')) #True
- # 获取属性
- print(getattr(obj,'name')) #egon
- getattr(obj,'say_hi')() #hi,egon
- print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
- # 设置属性
- setattr(obj,'sb','value') #setattr(x, 'y', v) is equivalent to ``x.y = v''setattr(obj,'show_name',lambda self:self.name+'sb')
- print(obj.__dict__) #{'name': 'egon', 'age': 73, 'sb': 'value', 'show_name': <function <lambda> at 0x0000000002985620>}
- print(obj.show_name(obj)) #egonsb
- # 删除属性
- delattr(obj,'age')
- delattr(obj,'show_name')
- delattr(obj,'show_name111')# 不存在, 则报错
- print(obj.__dict__)
- # 类也是对象
- class Foo(object):
- staticField = "old boy"
- def __init__(self):
- self.name = 'wupeiqi'
- def func(self):
- return 'func'
- @staticmethod
- def bar():
- return 'bar'
- print(getattr(Foo, 'staticField'))
- print(getattr(Foo, 'func'))
- print(getattr(Foo, 'bar'))
- import sys
- def s1():
- print( 's1')
- def s2():
- print ('s2')
- this_module = sys.modules[__name__]
- print(hasattr(this_module, 's1')) #True
- print(getattr(this_module, 's2')) #<function s2 at 0x0000000002955620>
- print(this_module) #<module '__main__' from 'D:/ 复习 / 6_9.py'>
__str__和__repr__
改变对象的字符串显示__str__,__repr__
自定制格式化字符串__format__
- '''
- str 函数或者 print 函数 --->obj.__str__()
- repr 或者交互式解释器 --->obj.__repr__()
- 如果__str__没有被定义, 那么就会使用__repr__来代替输出
- 注意: 这俩方法的返回值必须是字符串, 否则抛出异常
- '''
- format_dict={
- 'nat':'{obj.name}-{obj.addr}-{obj.type}',# 学校名 - 学校地址 - 学校类型
- 'tna':'{obj.type}:{obj.name}:{obj.addr}',# 学校类型: 学校名: 学校地址
- 'tan':'{obj.type}/{obj.addr}/{obj.name}',# 学校类型 / 学校地址 / 学校名
- }
- class School:
- def __init__(self,name,addr,type):
- self.name=name
- self.addr=addr
- self.type=type
- def __repr__(self):
- return 'School(%s,%s)' %(self.name,self.addr)
- def __str__(self):
- return '(%s,%s)' %(self.name,self.addr)
- def __format__(self, format_spec):
- # if format_spec
- if not format_spec or format_spec not in format_dict:
- format_spec='nat'
- fmt=format_dict[format_spec]
- return fmt.format(obj=self)
- s1=School('oldboy1','北京','私立')
- print('from repr:',repr(s1)) #from repr: School(oldboy1, 北京)
- print('from str:',str(s1)) #from str: (oldboy1, 北京)
- print(s1) #(oldboy1, 北京)
- print(format(s1,'nat')) #oldboy1 - 北京 - 私立
- print(format(s1,'tna')) #私立: oldboy1: 北京
- print(format(s1,'tan')) #私立 / 北京 / oldboy1
- print(format(s1,'asfdasdffd')) #oldboy1 - 北京 - 私立
%s 和 %r
- class B:
- def __str__(self):
- return 'str : class B'
- def __repr__(self):
- return 'repr : class B'
- b = B()
- print('%s' % b) #str : class B
- print('%r' % b) #repr : class B
item 系列
__getitem__\__setitem__\__delitem__
- class Foo:
- def __init__(self,name,age):
- self.name=name
- self.age=age
- def __getitem__(self, item):
- print(self.__dict__[item])
- def __setitem__(self, key, value):
- self.__dict__[key]=value
- def __delitem__(self, key):
- print('del obj[key] 时, 我执行')
- self.__dict__.pop(key)
- def __delattr__(self, item):
- print('del obj.key 时, 我执行')
- self.__dict__.pop(item)
- f1=Foo('sb',12)
- print(f1.__dict__)
- f1['age']=18
- f1['age1']=19
- del f1.age1 #__delattr__
- del f1['age'] #__delitem__
- f1['name']='alex'
- print(f1.name) #__getitem__
- item
__del__ 析构方法 当对象在内存中被释放的时候, 自动触发执行
析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
- class Foo:
- def __del__(self):
- print('执行我啦')
- f1=Foo()
- del f1
- print('------->')
简单实现
__new__ 开辟空间 构造方法
- class A:
- def __init__(self):
- self.x = 1
- print('in init function')
- def __new__(cls, *args, **kwargs):
- print('in new function')
- return object.__new__(A)
- a = A() #先执行__new__ 再执行__init__
- print(a.x) # 1 对象. 属性
实例化的过程
- class Singleton:
- def __new__(cls, *args, **kw):
- if not hasattr(cls, '_instance'):
- cls._instance = object.__new__(cls)
- return cls._instance
- one = Singleton()
- two = Singleton()
- two.a = 3
- print(one.a) #3
- # one 和 two 完全相同, 可以用 id(), ==, is 检测
- print(id(one))
- print(id(two))
- print(one == two)# True
- print(one is two)# True
单例模式
__call__ 对象后面加 (), 触发执行
注: 构造方法的执行是由创建对象触发的, 即: 对象 = 类名 () ; 而对于 __call__ 方法的执行是由对象后加括号触发的, 即: 对象 () 或者 类 ()()
- class Foo:
- def __init__(self):
- pass
- def __call__(self, *args, **kwargs):
- print('__call__')
- obj = Foo() # 执行 __init__
- obj() # 执行 __call__
代码示例
with 和 __enter__ ,__exit__ with 本质就是执行了 enter 和 exit 方法
__len__ 长度
__hash__ 哈希
__eq__ 相同
- class A:
- def __init__(self):
- self.a = 1
- self.b = 2
- def __eq__(self,obj):
- if self.a == obj.a and self.b == obj.b:
- return True
- a = A()
- b = A()
- print(a == b)
- __eq__
- class FranchDeck:
- ranks = [str(n) for n in range(2,11)] + list('JQKA')
- suits = ['红心','方板','梅花','黑桃']
- def __init__(self):
- self._cards = [(rank,suit) for rank in FranchDeck.ranks
- for suit in FranchDeck.suits]
- def __len__(self):
- return len(self._cards)
- def __getitem__(self, item):
- return self._cards[item]
- deck = FranchDeck()
- print(deck._cards)
- print(deck[0])
- from random import choice
- print(choice(deck))
- print(choice(deck))
纸牌
- class Person:
- def __init__(self,name,age,sex):
- self.name = name
- self.age = age
- self.sex = sex
- def __hash__(self):
- return hash(self.name+self.sex)
- def __eq__(self, other):
- if self.name == other.name and self.sex == other.sex:return True
- p_lst = []
- for i in range(84):
- p_lst.append(Person('egon',i,'male'))
- print(p_lst)
- print(set(p_lst)) #{<__main__.Person object at 0x0000000001F48080>}
一道面试题
面向对象 2
来源: http://www.bubuko.com/infodetail-3087887.html