1. 程式人生 > >類的相關內置函數及反射

類的相關內置函數及反射

內置函數 count() iss 獲取 調用 bbf 字符 http 查找

類變量的內存位置相關練習

1.1

技術分享圖片
class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display = [11,22]


s1 = StarkConfig()
result1 = s1.get_list_display()
print(result1) # 33 result2 = s1.get_list_display() print(result2) # 33 33
練習1

技術分享圖片

1.2

技術分享圖片
class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display 
= [11,22] s1 = StarkConfig() s2 = StarkConfig() result1 = s1.get_list_display() print(result1) # [33] result2 = s2.get_list_display() print(result2) # [33,33]
練習2

技術分享圖片

1.3

技術分享圖片
class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,
33) return self.list_display class RoleConfig(StarkConfig): list_display = [11,22] s1 = StarkConfig() s2 = RoleConfig() result1 = s1.get_list_display() print(result1) # [33] result2 = s2.get_list_display() print(result2) # [33,11,22]
練習3

技術分享圖片

類的相關內置函數

1.1 issubclass(參數1,參數2)

檢查第一個參數是否是第二個參數的子類及子類的子類(比較圓滑,只要是長輩都返回True),返回True和Flase,可以判斷對象是不是由某一個指定類或其父類

技術分享圖片
class Base(object):
    pass


class Foo(Base):
    pass


class Bar(Foo):
    pass


print(issubclass(Foo, Base))
print(issubclass(Foo, object))
print(issubclass(Bar, Foo))
print(issubclass(Bar, Base))
print(issubclass(Bar, object))

# 輸出結果:
True
True
True
True
True
View Code

1.2 type

獲取當前對象是由哪個類創建,只承認當前對象的直接上級(比較死板),可以判斷對象是不是由某一個指定類創建

技術分享圖片
class Foo(object):
    pass

obj = Foo()

print(obj,type(obj)) # 獲取當前對象是由那個類創建。

# 輸出結果:
<__main__.Foo object at 0x00000272D5EB6320> <class __main__.Foo>

# 可以人為判斷

if type(obj) == Foo:
    print(obj是Foo類型)

# 因判斷為True
# 輸出結果:
obj是Foo類型
View Code

1.3 isinstance(對象,類)

檢查第一個參數(對象)是否是第二個參數(類及父類)的實例,返回True和Flase

技術分享圖片
class Foo(object):

    def f1(self):
        pass

    def f2(self):
        pass

    def f3(self):
        pass

obj = Foo()
Foo.f1(obj) # 把f1當做函數

obj = Foo()
obj.f1()    # 把f1當做方法,自動傳self值
View Code 技術分享圖片
class Base(object):
    pass

class Foo(Base):
    pass

obj1 = Foo()

print(isinstance(obj1,Foo)) # True
print(isinstance(obj1,Base)) #True     由此可見是其父類也返回True

obj2 = Base()
print(isinstance(obj2,Foo))  #Flase      由此可見,是其子類不可以,返回Flase
View Code

用科學的方法判斷是函數還是方法

我們一般認為,寫在類中的就可以叫做方法,寫在外面的就可以叫做函數

科學的方法判斷就是判斷它是不是方法類或函數類中的,因為在python中,一切皆對象,方法和函數也是某個類的對象

MethodType(方法),FunctionType(函數)

技術分享圖片
from types import MethodType,FunctionType
def check(arg):
    """
    檢查arg是方法還是函數?
    :param arg:
    :return:
    """
    if isinstance(arg,MethodType): # 如果arg是MethodType類的實例

        print(arg是一個方法)
    elif isinstance(arg,FunctionType): # 如果arg是FunctionType類的實例
        print(arg是一個函數)
    else:
        print(不知道是什麽)

def func():
    pass

class Foo(object):
    def detail(self): # 默認傳入self參數
        pass
    @staticmethod
    def xxx(): # 沒有默認參數
        pass


check(func) #這是一個函數
obj = Foo()
check(obj.detail) # 這是一個方法
check(obj.xxx)  # 這是一個函數

"""
由上述可知,判斷是方法還是函數,也看有沒有其怎麽調用或是否有默認self參數傳入
"""
View Code

小結:

對象.xxx --> xxx就是方法

類.xxx --> xxx就是函數

xxx --> xxx就是函數

反射

geattr(對象,字符串)

根據字符串為參數,去對象中尋找與之同名的成員

去模塊中尋找

技術分享圖片
"""
建立一個handler.py文件

"""
f0 = 9

def f1():
    print(F1)

def f2():
    print(F2)

def f3():
    print(F3)

def f4():
    print(F4)

def f5():
    print(F5)

"""
同目錄級引入上述handler模塊

"""

import handler

while True:
    print("""
    系統支持的函數有:
        1. f1
        2. f2
        3. f3
        4. f4
        5. f5
    """)
    val = input("請輸入要執行的函數:") # val = "f1"

    if hasattr(handler,val):
        func_or_val = getattr(handler,val)     # 根據字符串為參數,去模塊中尋找與之同名的成員。
        if isinstance(func_or_val,FunctionType):
            func_or_val()
        else:
            print(func_or_val)
    else:
        print(handler中不存在輸入的屬性名)
View Code

面向對象中用geattr

技術分享圖片
 1 class Foo(object):
 2 
 3     country = "中國"
 4 
 5     def func(self):
 6        pass
 7 
 8 v = getattr(Foo,func) # Foo.func # 根據字符串為參數,去類中尋找與之同名的成員。
 9 print(v) # 輸出fun的內存地址,通過類查找,此時 func是個函數
10 
11 obj = Foo()
12 v = getattr(obj,"func") # obj.func # 根據字符串為參數,去對象中尋找與之同名的成員。
13 print(v)  # 輸出func的內存地址,通過對象查找,此時func是個方法
反射簡單示例

hasattr

根據字符串的形式,去判斷對象中是否有成員。

技術分享圖片
import xx

v3 = hasattr(xx,x1)
v4 = hasattr(xx,f1)
v4 = hasattr(xx,f1)
v5 = hasattr(xx,xxxxxxx)
print(v3,v4,v5)
 # True True False
View Code

setattr

根據字符串的形式,去判斷對象中動態的設置一個成員(在內存中)

技術分享圖片
class Foo(object):

    def __init__(self,a1):
        self.a1 = a1
        self.a2 = None

obj = Foo(1)


v1 = getattr(obj,a1)
print(v1) # 1

setattr(obj,a2,2)    # 若__init__沒有a2參數,不建議這麽寫,因為沒有人知道你其中還有其    
                              # 他參數   若想寫,最好在__init__那添加 a2 = None
v2 = getattr(obj,a2)
print(v2)  # 2                                    
View Code

delattr

根據字符串的形式,去判斷對象中動態的設置一個成員(內存中)

技術分享圖片
import xx

delattr(xx,x1)
v9 = getattr(xx,x1)
print(v9)
# 因刪除了 x1 所以會報錯

# AttributeError: module ‘xx‘ has no attribute ‘x1‘
View Code

getattr的實際應用

技術分享圖片
class Account(object):
    func_list = [login, logout, register]

    def login(self):
        """
        登錄
        :return:
        """
        print(登錄111)

    def logout(self):
        """
        註銷
        :return:
        """
        print(註銷111)

    def register(self):
        """
        註冊
        :return:
        """
        print(註冊111)

    def run(self):
        """
        主代碼
        :return:
        """
        print("""
            請輸入要執行的功能:
                1. 登錄
                2. 註銷
                3. 註冊
        """)

        choice = int(input(請輸入要執行的序號:))
        func_name = Account.func_list[choice-1]

        # func = getattr(Account,func_name) # Account.login
        # func(self)

        func = getattr(self, func_name)  # self.login
        func()

obj1 = Account()
obj1.run()

obj2 = Account()
obj2.run()
練習



類的相關內置函數及反射