2011-12-21 3 views
1

У меня есть 2 модуля, каждый из которых содержит класс.
Моя основная программа создает экземпляр объекта класса One, который создает экземпляры многих объектов класса Two.
Мне нужно иметь возможность вызвать функцию класса 1 из экземпляров класса 2.
Это общий вид, что у меня есть:Как вы можете вызвать функцию создателя экземпляра в python?

модуль mod_one.py:

import mod_two 

class One: 
    def __init__(self): 
     self.new_instance = Two() 

    def call_back_func(self): 
     # This function should be called 
     # from the new instance of class Two() 

модуль mod_two.py:

class Two: 
    def __init__(self): 
     # Call call_back_func() of module mod_one 

Единственный способ я нашел, чтобы передать функцию обратного вызова function call_back_func() в качестве аргумента для класса Two, например:

self.new_instance = Two(self.call_back_func) 

, но я хотел бы знать, есть ли лучший способ сделать это.

+3

Это совершенно правильный способ сделать это, поскольку он не вводит круговую зависимость. –

+0

Я думаю, что прохождение 'self.call_back_func' конструктора - довольно хороший способ сделать это. – NPE

ответ

1

Что вы делаете, это действительно так. Обратите внимание: __init__ не является конструктором. Это только метод инициализации. (__new__ является метод конструктор Пайтона)

Больше на эту тему можно найти в вопросе Python's use of __new__ and __init__?

+0

-1: Я не вижу существенного способа, в котором '__init__' не похож на концепцию конструкторов с других языков. '__new__' OTOH - это концепция, которая не существует в таких языках, как Java/C++, поэтому я не понимаю, как вы можете сказать, что она лучше подходит для этой концепции. Я думаю, что «' __init__' не является конструктором »- это миф и бесполезный в этом. Официальные документы python даже ссылаются на '__init__' как на конструктор! http://docs.python.org/reference/datamodel.html#basic-customization – Ben

+0

Конструкция объекта выполняется при выходе из '__new__' ... – gecco

+0

Перед тем, как ввести конструктор, который присваивает значения членам. Точно так же, как в Java и C++. Единственное отличие состоит в том, что они не предоставляют никаких средств, таких как '__new__', чтобы настроить процесс создания нового экземпляра. – Ben

0

Я думаю, что вам не хватает объект здесь. В частности, Creational Builder Pattern

class OneTwoBuilder: 

    def createOne(self, num_of_two=0): 
     o = One() 
     child = [] 
     for _ in xrange(num_of_two): 
      t = Two() 
      o.callback(t) 
      child.append(t) 
     o.setChilds(child) 
     return o 
2

Я думаю, что есть компромисс между простотой здесь и слабой связанности. На мой взгляд, простота будет передавать обратный вызов объекту, в то время как свободная связь будет использовать фреймворк для передачи сигналов между объектами.

Например, если вы используете blinker сигнализации библиотеку вы могли бы использовать этот альтернативный дизайн:

from blinker import signal 

class One: 
    def __init__(self): 
     self.two = Two() 
     self.two.some_signal.connect(self.callback) 

    def callback(self, data): 
     print 'Called' 

class Two: 
    some_signal = signal('some_signal') 

    def process(self): 
     # Do something         
     self.some_signal.send() 

one = One() 
one.two.process() 

В коде выше, Two объект, даже не знаю, есть ли какой-либо другой объект заинтересован в его внутренние изменения состояния , Однако он уведомляет об этом, излучая сигнал, который может быть использован другими объектами (в данном случае объектом One) для выполнения определенного действия.

Хорошим примером такого подхода является графический интерфейс. Когда создается виджет кнопки, не нужно передавать обратный вызов, который должен выполняться при нажатии кнопки. Тем не менее, кнопка выдает сигнал щелчка и любой обратный вызов подписывается на этот сигнал для выполнения требуемого действия.

+0

Спасибо, я дам ему попробовать, хотя приведенные выше комментарии побуждают меня «не исправлять» если он не сломан »:) – user1102018

+0

Я согласен с этими комментариями, я считаю, что вам просто нужно знать о других альтернативах на всякий случай, если в будущем вы обнаружите, что слишком много обратных вызовов. – jcollado

+0

Я пришел сюда для примера с миганием о том, как вызвать метод объекта, если выдается сигнал. Я нашел ваш пример очень полезным, спасибо. – Jabba

Смежные вопросы