【问题标题】:Share values between objects in the same Python module [closed]在同一 Python 模块中的对象之间共享值 [关闭]
【发布时间】:2013-11-27 23:31:18
【问题描述】:

文件引擎.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()

完成此任务的最佳方法是什么?由于 Event 类的限制(它实际上是我正在将新功能拼接到的第三方库的子类),我无法执行 e = Event(engine) 之类的操作。

深入解释:

为什么我不使用e = Event(engine)

因为 Event 实际上是第三方库的子类。此外,process() 是一种内部方法。所以这个类实际上是这样的:

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)

我的新模块还必须与已经使用 Event 类的现有代码无缝运行。所以我不能将引擎对象添加到每个 _process() 调用或 init 方法。

【问题讨论】:

  • 类定义之间,还是模块内的所有对象?
  • 模块内所有对象之间,已编辑标题。
  • 你试过globals()['variable']吗?但它很脏,我认为你的设计模型有问题。
  • 如果有多个Engine类型的对象,Event.process()怎么知道选择哪一个?
  • 看起来我们这里有一个XY problem。你不应该问如何做这个 distry 技巧。您应该询问如何处理这个库,提及哪个库以及您想要实现的目标。将此作为可能的解决方案提及,并询问它是否正确,如果不是如何解决它或有什么替代方案。试图修复我们不知道它是什么的东西是困难并且会产生很多歧义和误解。

标签: python


【解决方案1】:

functools.partial 可能会有所帮助:

#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)

现在,当第 3 方库创建 Event 时,会自动传递 engine

【讨论】:

  • 哦,太好了!这可能是最好的选择。
  • 但是,这仅适用于您必须将Event 传递给您还没有透露的第三方库。
【解决方案2】:

"由于 Event 类的限制(它实际上是一个子类 我正在将新功能拼接到的第三方库)我 不能做像 e = Event(engine) 这样的事情。”

您似乎担心 Event 正在继承某个其他类,因此您无法更改该类的构造方法。

您的问题类似于this other one。幸运的是,super().__init__() 方法为您完成了这项工作。

考虑以下示例:

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

【讨论】:

  • 这只有在他构造Event时才有帮助。第 3 方库可能正在从传入的类对象构造事件。
  • @Robᵩ:如果是这样,那么 OP 应该提到它。
  • 到目前为止唯一明智的答案...
【解决方案3】:

为什么不将变量传递给process 函数?您说类的构造函数不能更改,但您似乎正在定义process。做吧:

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

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

【讨论】:

  • 查看我的编辑以获得更好的解释
猜你喜欢
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2015-11-16
  • 2013-03-02
相关资源
最近更新 更多