Иерархия объектов Python; Ссылка на экземпляр владельца? - PullRequest
3 голосов
/ 20 марта 2012

Не существует ли магического python-способа доступа к экземпляру класса, который имеет ссылку на текущее «я» внутри него? то есть:

class A(object):
    def __init__(self):
        self.B = B()

    def say_hi(self):
        print "Hi"

class B(object)
    def __init__(self):
        __get_owner_ref__.say_hi()

A()

get_owner_ref - волшебная пуля, которой не существует. Есть ли в Python функция для такого поведения?

Да, я знаю, что могу передать ссылку конструктору, но я ищу более элегантное решение.

Ответы [ 5 ]

3 голосов
/ 20 марта 2012

Нет, вы должны сделать что-то вроде этого

class A(object):
    def __init__(self):
        self.B = B(parent=self)

    def say_hi(self):
        print "Hi"

class B(object)
    def __init__(self, parent):
        self.parent = parent   # you don't need to do this, but it might be a good idea
        parent.say_hi()

A()
2 голосов
/ 20 марта 2012

Технически, вы можете использовать sys._getframe:

class B(object):
    def __init__(self):
        import sys
        a = sys._getframe(1).f_locals['self']
        a.say_hi()

Но вы не должны этого делать .Это может привести к путанице, сломать новые реализации Python, усложнит отладку и может сломаться.Существует причина, по которой sys._getframe указан в 5 лет плохих идей .

Вместо этого передайте ссылку либо на родительский объект, либо на метод say_hi.

2 голосов
/ 20 марта 2012

Насколько я знаю, такой функции не существует.Кроме того, передача его в качестве ссылки на конструктор и вызов self.parent.say_hi() гораздо более явный и (действительно) элегантный.И явное лучше, чем неявное или использующее магические возможности языка.

2 голосов
/ 20 марта 2012

Нет, нет хорошего способа сделать это.Передайте ссылку инициализатору.

Чтобы исключить вопросы, в большинстве случаев, вероятно, возможно найти владельца эвристически, осмотрев стек, что-то вроде этого вопроса .Но это будет хрупким, глючным и трудным для понимания. И это идет вразрез с «явной> неявной» философией.

1 голос
/ 21 марта 2012

С другой стороны, то, что вы ищете, очень похоже на дескрипторы .Рассмотрим:

class Agent(object):
    def __get__(self, obj, objtype):
        print 'Agent %s called from %s ' % (id(self), obj.name)

class X(object):
    agent = Agent()

    def __init__(self, name):
        self.name = name

a = X('Foo')
a.agent

b = X('Bar')
b.agent

Здесь agent прикреплен к двум разным экземплярам и «знает» каждый раз, какой экземпляр хочет с ним поговорить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...