[英]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_minute
, minutes_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.