簡體   English   中英

Python 類實例自省

[英]Python class instances introspection

從內省的角度來看,有沒有一種方法可以在不創建實例的情況下獲取類實例變量。 創建實例時很容易:

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

class Sub(Super):
    pass

a = Super("Nice_Name")

print(a.__dict__.keys())

但是我想在不創建實例的情況下獲取該信息,只是為了進行內省。 有辦法嗎?

不,你不能,因為 python 不是靜態類型語言,所以在實例化對象之前,該對象沒有類型。 例如,想象一個這樣的類:

class A:
def __init__(self):
    self.a = "a"

def change_type(self):
    self.a = 1

在實例化對象之前, self.a的類型是什么? 如果您需要自省,則不能使用 python。

我一直在對此進行一些研究,似乎在某些情況下您可以執行此操作,但是沒有完美的解決方案:

  1. 如果您使用@property裝飾器定義實例變量,那么它會在執行dir(class_type)
  2. 同樣,您可以使用__slots__魔術變量定義允許的實例屬性列表,然后只需執行class_type.__slots__即可獲取您的實例變量。
  3. 有點hacky,但您可以閱讀該類的源代碼,然后查找對self.varname = expression任何引用。 這當然假設self將始終是類實例的引用方式,並且在內部類或self被重新分配給另一個 varname 等情況下會失敗。 也不會選擇像setattr(self, varname, expression) ,你需要其他邏輯來檢測。
  4. 可能比選項 #3 更健壯,您可以使用ast模塊並使用它來解析類源代碼。 然后進行一些搜索以查找可能將屬性寫入類self表達式。

看看這個例子:

import dill, re

class Test:
    __slots__ = ["x","y","z"]
    def __init__(self):
        self.x = 0
        self.y = 1
        self.z = 2
    @property
    def q(self):
        return self.x

# this grabs those defined using __slots__ or @property
print(dir(Test))

# this looks at class source
# may need to play around with the regex more...
s = dill.source.getsource(Test)
var_finder = re.compile("self\.([^\W]+)\s*\=")
print(set(var_finder.findall(s)))

我個人認為在你的類上添加__slots__是最好的方法。 對於 sphinx 文檔,這是我的用例,這似乎是讓autosummary指令獲取這些實例變量的最佳方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM