我尝试获取实例变量的类,我认为这很简单,但目前我无法弄明白。
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这样的类。
感谢您的帮助! :)
答案 0 :(得分:2)
你做不到。
在Python中,变量只是值的名称。值可以有多个名称,例如60
可能被称为seconds_per_minute
,minutes_per_hour
,甚至speed_limit_mph
,这些名称显然彼此无关。值也可以没有名称,例如print(60)
不会给60
任何名称。
要记住的一点是,当你调用一个函数时,你的参数是passed by assignment。也就是说,函数的参数成为您传入的值的新名称。因此被调用的函数不知道您使用的是您传递的对象的名称,它只知道该对象的自己的名称
在这种情况下,对象本身不知道它在哪个类中创建。你知道它,因为你知道对象的名称(它是B().b
)。但是对象的名称没有传递给被调用的函数,因此getClassOfVariable
无法确定您的A
对象是在哪个类中创建的。
那么,如何解决这个限制?最简单的方法是将此信息提供给构造函数中的A
对象,方法是将type(self)
(或self.__class__
作为Python 2.x经典类)作为参数传递给{{1并在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
。
答案 1 :(得分:0)
您可以为属性使用描述符。在描述符的__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
中定义;如果那个实例得到传递,它可能会丢失它的上下文,并且在内省时,添加的属性可能看起来确实很奇怪。 - 但是对于这个简单的例子,似乎没问题。也许有评论,甚至编辑的downvotes将阐明。添加属性似乎太容易了,也许应该有一些保护措施。或者value.defining_class
可能只是字符串instance.__class__
- 为此而编辑