如何从 class 变量(从 class 外部)获取 class 实例?
How to fetch class instance from class variable (from outside the class)?
假设我有这个:
from PySide2 import QtWidgets
class MyClass(object):
def __init__(self, parent=None):
self.class_variable = QtWidgets.QWidget()
class_instance = MyClass()
variable = class_instance.class_variable
class_instance_returned = mystery_method(variable) # How to make this return class_instance?
我应该如何定义 mystery_method
以便 return 成为 class_instance
实例?
我遇到的真实情况是,我正在发送一个 QWidget
,我将其用作将 .ui 文件加载到函数中的基本实例。在这个函数中,我需要弄清楚它属于哪个 class 实例。
Python 2.7
class MyClass(object):
def foo():
return 'bar'
instance = MyClass()
def mystery_method(method):
return method.im_self.__class__
print mystery_method(instance.foo)
Python 3
class MyClass(object):
def foo():
return 'bar'
instance = MyClass()
def mystery_method(method):
return method.__self__.__class__
print mystery_method(instance.foo)
编辑
OP 编辑后:
class ParentClass():
def foo():
return 'bar'
class MyClass(object):
def __init__(self, parent=None):
self.instance_attribute = ParentClass()
def mystery_method(method):
return method.__class__
class_instance = MyClass()
print mystery_method(class_instance.instance_attribute)
一种方法是我们将 foo
定义为自定义 属性,即 returns 其值和获取其值时的相关实例:
from collections import namedtuple
class Prop(object):
def __init__(self, val):
self.val = val
def __get__(self, instance, type):
return namedtuple('Prop', ('value', 'instance'))(self.val, instance)
def __set__(self, instance, val):
self.val = val
class MyClass(object):
foo = Prop('bar')
现在在你的程序中你可以显式使用它的值和相关的实例分别使用foo
的value
和instance
属性.
演示:
>>> instance = MyClass()
>>> instance.foo
Prop(value='bar', instance=<__main__.MyClass object at 0x10effbcd0>)
>>> instance.foo.value
'bar'
>>> instance.foo.instance
<__main__.MyClass object at 0x10effbcd0>
通常你不能(至少在系统中的所有对象中进行大量搜索是不可能的)但是如果你想要的只是找到 class 的哪些实例匹配一个特定的值那么它是公平的简单。
您可以创建一组所有实例并遍历它们以找到您需要的。
from weakref import WeakSet
class MyClass(object):
_instances = WeakSet()
def __init__(self, foo):
self._instances.add(self)
self.foo = foo
@classmethod
def findFoo(cls, foo):
return [instance for instance in cls._instances if instance.foo == foo]
>>> instance1 = MyClass('bar')
>>> instance2 = MyClass('baz')
>>> MyClass.findFoo('baz')
[<__main__.MyClass object at 0x7f6723308f50>]
>>> MyClass.findFoo('bar')
[<__main__.MyClass object at 0x7f6723308c50>]
请注意,删除对象不会立即将其删除,它可能要等到垃圾回收后才会删除:
>>> del instance1
>>> MyClass.findFoo('bar')
[<__main__.MyClass object at 0x7f6723308c50>]
>>> import gc
>>> gc.collect()
16
>>> MyClass.findFoo('bar')
[]
但是一般来说,您最好保留对原始对象的引用并只使用它。
此外,请注意,如果实例存储在多个对象中,您无法可靠地判断哪个实例持有 'bar'
:它们可能相同 'bar'
,也可能不同,以及是否它们相同或不同是一个实现细节。
假设我有这个:
from PySide2 import QtWidgets
class MyClass(object):
def __init__(self, parent=None):
self.class_variable = QtWidgets.QWidget()
class_instance = MyClass()
variable = class_instance.class_variable
class_instance_returned = mystery_method(variable) # How to make this return class_instance?
我应该如何定义 mystery_method
以便 return 成为 class_instance
实例?
我遇到的真实情况是,我正在发送一个 QWidget
,我将其用作将 .ui 文件加载到函数中的基本实例。在这个函数中,我需要弄清楚它属于哪个 class 实例。
Python 2.7
class MyClass(object):
def foo():
return 'bar'
instance = MyClass()
def mystery_method(method):
return method.im_self.__class__
print mystery_method(instance.foo)
Python 3
class MyClass(object):
def foo():
return 'bar'
instance = MyClass()
def mystery_method(method):
return method.__self__.__class__
print mystery_method(instance.foo)
编辑
OP 编辑后:
class ParentClass():
def foo():
return 'bar'
class MyClass(object):
def __init__(self, parent=None):
self.instance_attribute = ParentClass()
def mystery_method(method):
return method.__class__
class_instance = MyClass()
print mystery_method(class_instance.instance_attribute)
一种方法是我们将 foo
定义为自定义 属性,即 returns 其值和获取其值时的相关实例:
from collections import namedtuple
class Prop(object):
def __init__(self, val):
self.val = val
def __get__(self, instance, type):
return namedtuple('Prop', ('value', 'instance'))(self.val, instance)
def __set__(self, instance, val):
self.val = val
class MyClass(object):
foo = Prop('bar')
现在在你的程序中你可以显式使用它的值和相关的实例分别使用foo
的value
和instance
属性.
演示:
>>> instance = MyClass()
>>> instance.foo
Prop(value='bar', instance=<__main__.MyClass object at 0x10effbcd0>)
>>> instance.foo.value
'bar'
>>> instance.foo.instance
<__main__.MyClass object at 0x10effbcd0>
通常你不能(至少在系统中的所有对象中进行大量搜索是不可能的)但是如果你想要的只是找到 class 的哪些实例匹配一个特定的值那么它是公平的简单。
您可以创建一组所有实例并遍历它们以找到您需要的。
from weakref import WeakSet
class MyClass(object):
_instances = WeakSet()
def __init__(self, foo):
self._instances.add(self)
self.foo = foo
@classmethod
def findFoo(cls, foo):
return [instance for instance in cls._instances if instance.foo == foo]
>>> instance1 = MyClass('bar')
>>> instance2 = MyClass('baz')
>>> MyClass.findFoo('baz')
[<__main__.MyClass object at 0x7f6723308f50>]
>>> MyClass.findFoo('bar')
[<__main__.MyClass object at 0x7f6723308c50>]
请注意,删除对象不会立即将其删除,它可能要等到垃圾回收后才会删除:
>>> del instance1
>>> MyClass.findFoo('bar')
[<__main__.MyClass object at 0x7f6723308c50>]
>>> import gc
>>> gc.collect()
16
>>> MyClass.findFoo('bar')
[]
但是一般来说,您最好保留对原始对象的引用并只使用它。
此外,请注意,如果实例存储在多个对象中,您无法可靠地判断哪个实例持有 'bar'
:它们可能相同 'bar'
,也可能不同,以及是否它们相同或不同是一个实现细节。