python3-面向對象進階(內置方法)

面向對象進階:

  • isinstance和issubclass

  • 反射

  • __setattr__,__getattr,__delattr__

  • __setitem__,__getitem,__delitem__

  • __str__,__repr__,__format__

  • __del__

 

isinstance和issubclass

isinstance(obj,cls) 檢查obj是不是類cls的對象python

class Foo(object):
     pass
  
obj = Foo()
  
isinstance(obj, Foo)

issubclass(sub, super) 檢查sub類是不是super的派生類數據庫

class Foo(object):
    pass
 
class Bar(Foo):
    pass
 
issubclass(Bar, Foo)

 

反射

python面向對象中的反射:經過字符串的形式操做對象相關屬性。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'))
print(hasattr(obj,'say_hi'))

#獲取屬性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) # 不存在 'aaaa' 屬性的時候自動設置默認值‘不存在’, 不設默認值會報錯

#設置屬性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#刪除屬性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,則報錯

print(obj.__dict__)

 

類也是對象,也能夠反射spa

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')

 

反射的應用操作系統

class Service:
    def run(self):
        while True:
            inp = input('>>:').strip()      # cmd = 'get a.txt'
            cmds = inp.split()      # cmd = ['get', 'a.txt']

            if hasattr(self, cmds[0]):
                func = getattr(self, cmds[0])
                func(cmds)

    def get(self, cmds):
        print('get....')

    def put(self, cmds):
        print('put ....')

obj = Service()
obj.run()

 

 

__setattr__,__getattr,__delattr__

class Foo:
    x=1
    def __init__(self,y):
        self.y=y

    def __getattr__(self, item):
        print('----> from getattr:你找的屬性不存在')


    def __setattr__(self, key, value):
        print('----> from setattr')
        # self.key=value #這就無限遞歸了,你好好想一想
        # self.__dict__[key]=value #應該使用它

    def __delattr__(self, item):
        print('----> from delattr')
        # del self.item #無限遞歸了
        self.__dict__.pop(item)

#__setattr__添加/修改屬性會觸發它的執行
f1=Foo(10)
print(f1.__dict__) # 由於你重寫了__setattr__,凡是賦值操做都會觸發它的運行,你啥都沒寫,就是根本沒賦值,除非你直接操做屬性字典,不然永遠沒法賦值
f1.z=3
print(f1.__dict__)

#__delattr__刪除屬性的時候會觸發
f1.__dict__['a']=3#咱們能夠直接修改屬性字典,來完成添加/修改屬性的操做
del f1.a
print(f1.__dict__)

#__getattr__只有在使用點調用屬性且屬性不存在的時候纔會觸發
f1.xxxxxx

三者的用法演示

 

__setitem__,__getitem,__delitem__

# item系列
# 把類和對象和交互轉換成dict的形式

class Foo:  #Dict
    def __init__(self, name):
        self.name = name

    def __getitem__(self, item):
        return self.__dict__.get(item)

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]

obj = Foo('egon')

# 查看屬性
# print(obj['name'])

# 設置屬性
# obj['age'] = 18
# print(obj.age)
# print(obj.__dict__)

# 刪除屬性
del obj['name']
print(obj.__dict__)

 

__str__,__repr__,__format__

改變對象的字符串顯示__str__,__repr__code

自定製格式化字符串__format__orm

#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
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)blog

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))
print('from str: ',str(s1))
print(s1)

'''
str函數或者print函數--->obj.__str__()
repr或者交互式解釋器--->obj.__repr__()
若是__str__沒有被定義,那麼就會使用__repr__來代替輸出
注意:這倆方法的返回值必須是字符串,不然拋出異常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))

 

 

__del__

注:若是產生的對象僅僅只是python程序級別的(用戶級),那麼無需定義__del__,若是產生的對象的同時還會向操做系統發起系統調用,即一個對象有用戶級與內核級兩種資源,好比(打開一個文件,建立一個數據庫連接),則必須在清除對象的同時回收系統資源,這就用到了__del__

#__del__      回收系統操做資源

# f=open('settings.py')
# f.read()
# f.close() #回收操做系統的資源

# print(f)
# f.read()



class Open:
    def __init__(self,filename):
        print('open file.......')
        self.filename=filename

    def __del__(self):
        print('回收操做系統資源:self.close()')

f=Open('settings.py')
# del f #f.__del__()    
相關文章
相關標籤/搜索