簡體   English   中英

獲取實例變量的類

[英]Get class of instance variable

我嘗試獲取一個實例變量的類,我認為這很簡單,但是目前我不知道這一點。

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

class B():
  def __init__(self):
    self.b = A()

def getClassOfVariable(abc):
  print(abc)

getClassOfVariable(B().b)
<__main__.A object at 0x7f4b2652ac18>

例如,我有一個函數,其中將B()。b作為參數(無論如何)傳遞給函數,在此函數中,我需要定義變量的類,因此,類B()是我想要的函數。 我所知道的只是,在函數getClassOfVariable中,我僅獲得諸如B之類的類。

感謝您的幫助! :)

你不能那樣做。

在Python中,變量只是值的名稱。 值可以有許多名字,例如60可能被稱為seconds_per_minuteminutes_per_hour ,甚至speed_limit_mph ,而這些名字顯然沒有任何關系彼此。 值也可以完全沒有名稱,例如print(60)不會給出60任何名稱。

要記住的重要一點是,在調用函數時,參數是通過Assignment傳遞的 也就是說,函數的參數將成為您傳遞的值的新名稱。因此,被調用函數不知道為傳遞的對象使用了什么名稱,它只知道該對象的名稱。

在這種情況下,對象本身不知道在哪個類中創建對象。您知道它是因為知道對象的名稱(它是B().b )。 但是對象的名稱沒有傳遞給被調用的函數,因此getClassOfVariable無法確定創建A對象的類。

那么,如何解決此限制? 最簡單的方法是通過將type(self) (或對於Python 2.x經典類為self.__class__ )作為A()的參數傳遞給A對象,並在A該信息,從而在其構造函數中將此信息提供給A對象A.__init__()方法,如下所示:

class A():
  def __init__(self, owner=None):
    self.a = 1
    self.owner = owner

class B():
  def __init__(self):
    self.b = A(type(self))

然后,您可以檢查B().b.owner屬性,以找出哪個類創建了您的A對象。 但是,如果創建B的子類,則type(self)將是該子類,而不是B 如果在這種情況下仍需要獲取B ,則應傳遞B而不是type(self)

您可以為屬性使用描述符。 在描述符的__set__方法中,向其值添加一個屬性,該屬性可以在函數內部進行檢查。

from weakref import WeakKeyDictionary

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

class X:
    """A descriptor that knows where it was defined"""
    def __init__(self, default):
        self.default = default
        self.data = WeakKeyDictionary()

    def __get__(self, instance, owner):
        # we get here when someone calls x.d, and d is an X instance
        # instance = x
        # owner = type(x)
        return self.data.get(instance, self.default)

    def __set__(self, instance, value):
        # we get here when someone calls x.d = val, and d is an X instance
        # add an attribute to the value and assign the instance
        #value.defining_class = instance
        value.defining_class = instance.__class__
        self.data[instance] = value

class B:
    b = X(None) 
    def __init__(self):
        self.b = A()

def getClassOfVariable(abc):
    print(f'abc: {abc}')
    print(f'defining_class: {abc.defining_class}')

getClassOfVariable(B().b)

結果:

abc: <__main__.A object at 0x.....>
defining_class: <class '__main__.B'>

我從Python描述符Demystified中改編了這個描述符,編寫描述符時總是引用它。

警告:盡管可以,但是這感覺像是一種破解,當然還沒有經過陷阱的測試。 在這個例子中, A的實例添加了一個屬性, 表示它是在B中定義的; 如果該實例經過了一些傳遞,則可能會丟失其上下文,並且在內省時,添加的屬性確實確實看起來很奇怪。 -但對於這個簡單的例子,似乎還可以。 也許會對評論投反對票,甚至可以闡明編輯內容。 僅添加屬性似乎太容易了,也許應該涉及一些保護。 或者也許value.defining_class應該只是字符串instance.__class__ value.defining_class編輯為該效果

暫無
暫無

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

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