繁体   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