Как получить Python Object Parent? - PullRequest
3 голосов
/ 04 июля 2011

Итак, я пытаюсь получить объект, внутри которого находится пользовательский объект.Вот пример.

Предположим, что 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()

Итак, как бы я получил o изнутри теста?Я знаю, что мог бы написать функцию Test, чтобы передать ее с

o.test = Test(o)

, но я бы предпочел сделать это из определения класса.

Ответы [ 5 ]

7 голосов
/ 28 марта 2014

(я знаю, что это старый вопрос, но так как он остается без ответа ...)
Вы можете попробовать возиться с сборщиком мусора .Я собирался предложить посмотреть на объекты уровня модуля, но некоторые быстрые эксперименты с кодом дали это: Попробуйте функцию 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)

Результаты не простые, так что вы будетеВы должны применить свою собственную логику, чтобы определить, какой f тот, который вы ищете.Обратите внимание на 'f': <__main__.Foo object at ...> ниже:

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

Для получения бонусных баллов используйте gc.get_referents(*objs) для тех, чтобы проверить, есть ли в их списке тот же b.

Некоторые примечания / предостережения:

  • Я думаю, вы должны просто передать родительский объект Foo в Bar, либо в init, либо в другом методе.Это то, что я бы сделал, вместо моего предложения выше.
  • Этот SO-ответ указывает на некоторые проблемы, которые возникают у сборщика мусора при соединении в обе стороны - в настоящее время вы делаете это не так, но если выдо, к твоему сведению.
5 голосов
/ 05 июля 2011

вы могли бы сделать что-то вроде этого:

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
2 голосов
/ 11 февраля 2012

ну я не знаю, что именно вы пытаетесь.но я сделал что-то вроде этого.

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

и чтобы сделать родителя, вы можете сказать

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

Надеюсь, это поможет вам.

1 голос
/ 05 июля 2011

Если вы хотите, чтобы наследуемые объекты делали это правильно

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

class Bobcat(Test):
    def __init__(self):
        Test.__init__(self)
        self.b = 4 
0 голосов
/ 04 июля 2011

Вы говорите о наследовании?Не очень понятно, что вы имеете в виду, но если вы просто хотите сделать это:

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

Это прекрасно работает.

** ed: Это совсем не то, как вы должны делать наследование, если вы хотите сделать это.Однако, как вы описываете свою проблему, я думаю, что вы хотите создать древовидную структуру объектов, а не иметь классы, наследующие свойства друг от друга.

...