获取实例variab的类

2024-10-01 15:28:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图得到一个实例变量的类,我认为这是非常简单的,但目前我还不能搞清楚。你知道吗

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作为参数(whyever)传递给一个函数,在这个函数中,我需要定义它的变量的类,因此类B()是我在函数中想要的。 我只知道在函数getClassOfVariable中,我只得到像B这样的类

谢谢你的帮助!:)


Tags: 实例函数self参数定义objectinitmain
2条回答

你不能那样做。你知道吗

在Python中,变量只是值的名称。一个值可以有许多名称,例如60可能被称为seconds_per_minuteminutes_per_hour,甚至speed_limit_mph,而这些名称显然彼此无关。值也可以完全没有名称,例如print(60)没有给60任何名称。你知道吗

需要记住的一点是,调用函数时,参数是passed by assignment。也就是说,函数的参数成为传入值的新名称。因此,被调用的函数不知道您传递的对象使用的名称,它只知道该对象的名称。你知道吗

在这种情况下,对象本身不知道它是在哪个类中创建的。您知道它,因为您知道对象的名称(它是B().b)。但是对象的名称没有传递给被调用的函数,因此getClassOfVariable无法确定您的A对象是在哪个类中创建的。你知道吗

那么,如何绕过这个限制呢?最简单的方法是通过将type(self)(或self.__class__,对于python2.x经典类)作为参数传递给A()并在A.__init__()方法中处理它,将此信息提供给其构造函数中的A对象,如下所示:

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 Descriptors Demystified改编了这个描述符,我在编写描述符时总是引用它。你知道吗

警告:虽然这是可行的,但这感觉像是一个黑客,当然还没有测试过陷阱。在这个例子中,A的一个实例添加了一个属性,该属性表示它是在B中定义的;如果该实例被传递了一点,它可能会失去它的上下文,并且在内省时,添加的属性可能看起来很奇怪。-但对于这个简单的例子来说,这似乎是可以的。也许用评论,甚至编辑的否决票都能说明问题。仅仅添加一个属性似乎太容易了,也许应该有一些保护措施。或者value.defining_class应该是字符串instance.__class__编辑成这样

相关问题 更多 >

    热门问题