1

File engine.py:

class Engine(object):
    def __init__(self, variable):
        self.variable = variable

class Event(object):
    def process(self):
        variable = '123'  # this should be the value of engine.variable

Python

>>> from engine import Engine, Event
>>> engine = Engine('123')
>>> e = Event()
>>> e.process()

What's the best way to accomplish this? Because of limitations with the Event class (it's actually a subclass of a third-party library that I'm splicing new functionality into) I can't do something like e = Event(engine).

In depth explanation:

Why am I not using e = Event(engine)?

Because Event is actually a subclass of a third-party library. Additionally, process() is an internal method. So the class actually looks like this:

class Event(third_party_library_Event):
    def __init__(*args, **kwargs):
        super(Event, self).__init__(*args, **kwargs)

    def _process(*args, **kwargs):
        variable = engine.variable
        # more of my functionality here

        super(Event, self)._process(*args, **kwargs)

My new module also has to run seamlessly with existing code that uses the Event class already. So I can't add pass the engine object to each _process() call or to the init method either.

nathancahill
  • 10,452
  • 9
  • 51
  • 91
  • Between class definitions, or all objects inside a module? – Maciej Gol Nov 14 '13 at 19:21
  • Between all objects inside a module, edited title. – nathancahill Nov 14 '13 at 19:22
  • Have you tried `globals()['variable']`? But it's dirty, I think there is an issue in your design model. – Maciej Gol Nov 14 '13 at 19:24
  • If there are multiple objects of type `Engine`, how will `Event.process()` know which one to choose? – Robᵩ Nov 14 '13 at 19:25
  • There will only ever be one, but I see what you're saying. – nathancahill Nov 14 '13 at 19:27
  • Do you want `Event.process()` to have access to `engine` or to `engine.variable`? – Robᵩ Nov 14 '13 at 19:27
  • Please expand on why you can't modify `Event,__init__`. – Robᵩ Nov 14 '13 at 19:31
  • 2
    Looks like we've got an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) here. You shouldn't ask how to do this distry tricks. You should ask about how to deal with this library, mentioning which library and what you want to achieve. Mention this as a possible solution and ask whether it is correct if not how to fix it or what alternatives are there. Trying to fix something that we do not know what it is about it's *hard* and creates a lot of ambiguities and misunderstandings. – Bakuriu Nov 14 '13 at 19:50

3 Answers3

1

"Because of limitations with the Event class (it's actually a subclass of a third-party library that I'm splicing new functionality into) I can't do something like e = Event(engine)."

It appears that you're concerned that Event is inheriting some other class and you are therefore unable to alter the constructor method for the class.

Your question is similar to this other one. Fortunately, the super().__init__() method does this for you.

Consider the following example:

>>> class C(object):
    def __init__(self):
        self.b = 1


>>> class D(C):
    def __init__(self):
        super().__init__()
        self.a = 1

>>> d = D()
>>> d.a
1
>>> d.b  # This works because of the call to super's init
1
Community
  • 1
  • 1
Ashwin Balamohan
  • 3,303
  • 2
  • 25
  • 47
1

functools.partial might help:

#UNTESTED
class Engine(object):
    def __init__(self, variable):
        self.variable = variable

class Event(object):
    def __init__(self, engine):
        super().__init__()
        self.engine = engine
    def process(self):
        print self.engine.variable


engine = Engine('123')
Event = functools.partial(Event, engine)

ThirdPartyApiThatNeedsAnEventClass(Event)

Now, when the 3rd-party library creates an Event, it is automatically passed engine.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

Why not pass the variable in to the process function? You said the class's constructor can't be changed, but it seems like you are defining process. Just make it:

    def process(self, engine):
        variable = engine.variable
        <do stuff>

or

    def process(self, variable):
        <do stuff>
willy
  • 1,462
  • 11
  • 12