如何获得Python Object Parent?

时间:2021-03-06 16:45:25

So, I'm trying to get the object that a custom object is 'inside' of. Here's an example.

所以,我试图得到一个自定义对象在'内部'的对象。这是一个例子。

Assume that o is an object - it doesn't matter what kind, it can just store variables.

假设o是一个对象 - 它不管是什么类型,它只能存储变量。

o = Object()
class Test():
    def __init__(self):
        self.parent = o ## This is where I fall off; I want to be able to access
                        ## the o object from within the Test object

o.test = Test()

So, how would I get o from inside of Test? I know I could write the Test function to pass it in with

那么,我如何从Test内部获得o?我知道我可以编写Test函数来传递它

o.test = Test(o)

but I'd rather do it from inside the class definition.

但我宁愿从类定义中做到这一点。

5 个解决方案

#1


7  

(I know this is an old question but since it's unanswered...)
You could try messing with the garbage collector. Was going to suggest looking at the module level objects but some quick code experimentation gave this: Try the gc.get_referrers(*objs) function.

(我知道这是一个老问题,但因为它没有答案......)你可以尝试搞乱垃圾收集器。是建议查看模块级对象,但一些快速代码实验给出了这个:尝试gc.get_referrers(* objs)函数。

import gc

class Foo(object):
    """contains Bar"""
    def __init__(self, val):
        self.val = val
        self.bar = None

class Bar(object):
    """wants to find its parents"""
    def __init__(self, something):
        self.spam = something

    def find_parents(self):
        return gc.get_referrers(self)

The results aren't straightforward so you'll have to apply your own logic for how determine which f is the one you're looking for. Notice the 'f': <__main__.Foo object at ...> below:

结果并不简单,因此您必须应用自己的逻辑来确定哪个f是您正在寻找的f。注意下面的......>的 ':<__>

>>> f = Foo(4)
>>> b = Bar('ham')
>>> f.bar = b
>>> b.find_parents()
[{'bar': <__main__.Bar object at 0x7f3ec5540f90>, 'val': 4}, <frame object at 0x238c200>,
{'b': <__main__.Bar object at 0x7f3ec5540f90>,
    'Bar': <class '__main__.Bar'>,
    'f': <__main__.Foo object at 0x7f3ec5540f10>,    # <-- these might be
                                          # the droids you're looking for
    '__builtins__': <module '__builtin__' (built-in)>,
    '__package__': None, 'gc': <module 'gc' (built-in)>, '__name__': '__main__',
    'Foo': <class '__main__.Foo'>, '__doc__': None
}]

For bonus points, use gc.get_referents(*objs) on those to check if the same b is in their list.

对于奖励积分,请在这些积分上使用gc.get_referents(* objs)来检查列表中是否有相同的b。

Some notes/caveats:

一些注意事项/警告:

  • I think you should just pass the parent Foo object to Bar, either in init or another method. That's what I would do, instead of my suggestion above.
  • 我认为您应该在init或其他方法中将父Foo对象传递给Bar。这就是我要做的,而不是我上面的建议。
  • This SO answer points out some issues the garbage collector has when linking both ways - you're not currently doing that but if you do, fyi.
  • 这个SO答案指出了垃圾收集器在连接两种方式时遇到的一些问题 - 你目前没有这样做,但如果你这样做,那么。

#2


5  

you could do something like this:

你可以这样做:

class Object:
    def __setattr__(self, name, value):
        if isinstance(value, Test):
            value.set_parent(self)
        self.__dict__[name] = value

class Test:
    def set_parent(self, parent):
        self.parent = parent

o = Object()
o.test = Test()
assert o.test.parent is o

#3


2  

well, I donno what exactly you are trying. but I have done something like this.

好吧,我不知道你到底在想什么。但我做过这样的事情。

class Node(object):

    def __init__(self, name):
        self.parent = ''
        self.child = []
        self.name = name

    def setParent(self, parent):
        if isinstance(parent, tempNode):
            self.parent = parent.name
            parent.setChild(self.name)

    def setChild(self, child):
        self.child.append(child)

    def getParent(self):
        return self.parent

    def getChild(self):
        return self.child

and to make a parent you can say

你可以说,做一个父母

n1 = Node('Father')
n2 = Node('Son')
n2.setParent('Father') # it will set n1 as parent and n2 as child at the same time.

Hope this will help you.

希望这会帮助你。

#4


1  

If you want inheritable objects do it properly

如果您想要可继承的对象,请正确执行

class Test(object):
    def __init__(self):
        self.a = 1

class Bobcat(Test):
    def __init__(self):
        Test.__init__(self)
        self.b = 4 

#5


0  

Are you talking about inheritance? It's not very clear what you mean, but if you just want to do this:

你在谈论继承吗?你不是很清楚你的意思,但如果你只想这样做:

class Test():
  def __init__(self,o):
    self.parent = o
  def other_method(self):
    do_something_with(self.parent)

It works perfectly.

它完美地运作。

**ed: This is not at all how you should do inheritance, if you want to do that. However, the way you describe your problem I think you want to create a tree-like structure of objects, not have classes inherit properties from each other.

** ed:如果你想这样做,这根本不是你应该如何进行继承。但是,您描述问题的方式我认为您想要创建一个类似于树的对象结构,而不是让类继承彼此的属性。

#1


7  

(I know this is an old question but since it's unanswered...)
You could try messing with the garbage collector. Was going to suggest looking at the module level objects but some quick code experimentation gave this: Try the gc.get_referrers(*objs) function.

(我知道这是一个老问题,但因为它没有答案......)你可以尝试搞乱垃圾收集器。是建议查看模块级对象,但一些快速代码实验给出了这个:尝试gc.get_referrers(* objs)函数。

import gc

class Foo(object):
    """contains Bar"""
    def __init__(self, val):
        self.val = val
        self.bar = None

class Bar(object):
    """wants to find its parents"""
    def __init__(self, something):
        self.spam = something

    def find_parents(self):
        return gc.get_referrers(self)

The results aren't straightforward so you'll have to apply your own logic for how determine which f is the one you're looking for. Notice the 'f': <__main__.Foo object at ...> below:

结果并不简单,因此您必须应用自己的逻辑来确定哪个f是您正在寻找的f。注意下面的......>的 ':<__>

>>> f = Foo(4)
>>> b = Bar('ham')
>>> f.bar = b
>>> b.find_parents()
[{'bar': <__main__.Bar object at 0x7f3ec5540f90>, 'val': 4}, <frame object at 0x238c200>,
{'b': <__main__.Bar object at 0x7f3ec5540f90>,
    'Bar': <class '__main__.Bar'>,
    'f': <__main__.Foo object at 0x7f3ec5540f10>,    # <-- these might be
                                          # the droids you're looking for
    '__builtins__': <module '__builtin__' (built-in)>,
    '__package__': None, 'gc': <module 'gc' (built-in)>, '__name__': '__main__',
    'Foo': <class '__main__.Foo'>, '__doc__': None
}]

For bonus points, use gc.get_referents(*objs) on those to check if the same b is in their list.

对于奖励积分,请在这些积分上使用gc.get_referents(* objs)来检查列表中是否有相同的b。

Some notes/caveats:

一些注意事项/警告:

  • I think you should just pass the parent Foo object to Bar, either in init or another method. That's what I would do, instead of my suggestion above.
  • 我认为您应该在init或其他方法中将父Foo对象传递给Bar。这就是我要做的,而不是我上面的建议。
  • This SO answer points out some issues the garbage collector has when linking both ways - you're not currently doing that but if you do, fyi.
  • 这个SO答案指出了垃圾收集器在连接两种方式时遇到的一些问题 - 你目前没有这样做,但如果你这样做,那么。

#2


5  

you could do something like this:

你可以这样做:

class Object:
    def __setattr__(self, name, value):
        if isinstance(value, Test):
            value.set_parent(self)
        self.__dict__[name] = value

class Test:
    def set_parent(self, parent):
        self.parent = parent

o = Object()
o.test = Test()
assert o.test.parent is o

#3


2  

well, I donno what exactly you are trying. but I have done something like this.

好吧,我不知道你到底在想什么。但我做过这样的事情。

class Node(object):

    def __init__(self, name):
        self.parent = ''
        self.child = []
        self.name = name

    def setParent(self, parent):
        if isinstance(parent, tempNode):
            self.parent = parent.name
            parent.setChild(self.name)

    def setChild(self, child):
        self.child.append(child)

    def getParent(self):
        return self.parent

    def getChild(self):
        return self.child

and to make a parent you can say

你可以说,做一个父母

n1 = Node('Father')
n2 = Node('Son')
n2.setParent('Father') # it will set n1 as parent and n2 as child at the same time.

Hope this will help you.

希望这会帮助你。

#4


1  

If you want inheritable objects do it properly

如果您想要可继承的对象,请正确执行

class Test(object):
    def __init__(self):
        self.a = 1

class Bobcat(Test):
    def __init__(self):
        Test.__init__(self)
        self.b = 4 

#5


0  

Are you talking about inheritance? It's not very clear what you mean, but if you just want to do this:

你在谈论继承吗?你不是很清楚你的意思,但如果你只想这样做:

class Test():
  def __init__(self,o):
    self.parent = o
  def other_method(self):
    do_something_with(self.parent)

It works perfectly.

它完美地运作。

**ed: This is not at all how you should do inheritance, if you want to do that. However, the way you describe your problem I think you want to create a tree-like structure of objects, not have classes inherit properties from each other.

** ed:如果你想这样做,这根本不是你应该如何进行继承。但是,您描述问题的方式我认为您想要创建一个类似于树的对象结构,而不是让类继承彼此的属性。