【问题标题】:How to fetch class instance from class variable (from outside the class)?如何从类变量(从类外部)获取类实例?
【发布时间】:2017-04-03 09:02:00
【问题描述】:

假设我有这个:

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 以便它返回 class_instance 实例?

我的实际情况是我正在发送一个QWidget,我将其用作将.ui 文件加载到函数中的基本实例。在这个函数中,我需要弄清楚它属于哪个类实例。

【问题讨论】:

  • 你想要type
  • 不,我不想要这种类型。我想要实际的类实例。
  • 哎呀误会了。我认为在一般情况下这是不可能的。或者根本,真的……
  • 这个问题有无限可能的答案。你到底想要什么?返回 MyClass 的所有实例及其属性 foo == 'bar' 存储在全局范围内的方法?

标签: python pyside pyside2


【解决方案1】:

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 应该是类级别的数据属性,而不是方法。
  • 嗨@fredrik!您帖子上的代码仍然存在问题。看,您将foo 设置为__init__ 方法的局部变量,但随后您尝试将foo 传递给mystery_method,就好像fooMyClass 的方法一样。
  • @IvanChaer 是的,对不起......我在这里完全搞砸了。我再次编辑了我的问题。
  • @fredrik,如果你只需要一个对象的类,你可以使用_class_。考虑到这一点,我编辑了我的答案。如果我理解正确,请告诉我。
【解决方案2】:

我们可以将foo 定义为自定义属性,在获取其值时返回其值和相关实例:

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')

现在,您可以在您的程序中显式分别使用foovalueinstance 属性来使用其值和相关实例。

演示:

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

【讨论】:

    【解决方案3】:

    一般来说,您不能(至少在没有大量搜索系统中所有对象的情况下不会),但如果您只想找到某个类的哪些实例与特定值匹配,那么这相当容易。

    您可以创建一组所有实例并对其进行迭代以找到您需要的内容。

    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',也可能是不同的,以及它们是相同的还是不同的是一个实现细节。

    【讨论】:

      猜你喜欢
      • 2012-08-20
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多