面向对象2
# 面向对象
#类方法 静态方法 属性方法
普通的方法 类方法 静态方法 默认参数 self cls 无 操作的变量 操作对象的属性 操作静态属性 既不操作对象属性,也不操作类的属性 所属的命名空间 类 类 类 调用方式 对象 类/对象 类/对象 对应的装饰器 无 @classmethod @staticmethod
@classmethod (类方法 操作对象的属性 self默认参数 调用方法对象)
@property (方法伪装成属性一样使用,调用时候不加括号,也就没有参数)
@staticmethod (静态方法 既不操作对象属性,也不操作类的属性 无默认参数)
class A:
@classmethod 类方法
def c(cls):
print('cls')
@staticmethod 静态方法
def b():
print('B')
@property 方法变属性
def a(self):
print(1)
return 2
print(A().a)
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中的一切事物都是对象(都可以使用反射)
字符串 --> 程序中的变量名(类名\函数名\变量名\方法名\对象名)
getattr(命名空间,'key') == 命名空间.key 所有的a.b都可以被反射成getattr(a,'b')
class Foo(object): def __init__(self): self.__func() # _Foo__func # self.func() def __func(self): print('in Foo __func') # _Foo__func def func(self): print('in Foo func') class Son(Foo): def __func(self): print('in Son __func') # _Son__func def func(self): print('in Son func') s = Son() #in Foo __func # from sys import modules # a = 2 # b = 4 # print(getattr(modules[__name__],'c',123)) # print(getattr(modules[__name__],'a'))
四个可以实现反射的函数: 下面方法适用于类和对象(一切皆为对象,类本身也是一个对象) # 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__
__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)
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>}
字符串 --> 程序中的变量名(类名\函数名\变量名\方法名\对象名)