1. 程式人生 > >Python 面向對象的補充

Python 面向對象的補充

pan -- article 添加 alt bsp copy 無需 tle

isinstance(obj,cls)和issubclass(sub,super)

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

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

issubclass(sub, super)檢查sub類是否是 super 類的派生類

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

二 反射

1 什麽是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了計算機科學領域關於應用反射性的研究。它首先被程序語言的設計領域所采用,並在Lisp和面向對象方面取得了成績。

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

四個可以實現自省的函數

下列方法適用於類和對象(一切皆對象,類本身也是一個對象)

技術分享 hasattr(object,name) 技術分享 getattr(object, name, default=None) 技術分享 setattr(x, y, v)
技術分享 delattr(x, y) 技術分享 類也是對象 技術分享 反射當前模塊成員

導入其他模塊,利用反射查找該模塊是否存在某個方法

技術分享 module_test.py
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3  
 4 """
 5 程序目錄:
 6     module_test.py
 7     index.py
 8  
 9 當前文件:
10     index.py
11 """
12 
13 import module_test as obj
14 
15 #obj.test()
16 
17 print(hasattr(obj,‘test‘))
18 
19 getattr(obj,‘test‘)()

__setattr__,__delattr__,__getattr__

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

技術分享
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__

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

    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‘)
f1[‘age‘]=18
f1[‘age1‘]=19
del f1.age1
del f1[‘age‘]
f1[‘name‘]=‘alex‘
print(f1.__dict__)

技術分享
class Foo:
    def __init__(self,name):
        self.name=name

    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‘)
f1[‘age‘]=18
f1[‘age1‘]=19
del f1.age1
del f1[‘age‘]
f1[‘name‘]=‘alex‘
print(f1.__dict__)
技術分享

__del__

  析構方法,當對象在內存中被釋放時,自動觸發執行。

註:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,因為此工作都是交給Python解釋器來執行,所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。

class Foo:

    def __del__(self):
        print(‘執行我啦‘)

f1=Foo()
del f1
print(‘------->‘)

#輸出結果
執行我啦
------->

技術分享
class Foo:

    def __del__(self):
        print(‘執行我啦‘)

f1=Foo()
del f1
print(‘------->‘)

#輸出結果
執行我啦
------->

Python 面向對象的補充