【问题标题】:Managing class by instance按实例管理类
【发布时间】:2014-07-22 02:22:07
【问题描述】:

我做了一个复杂的课程,现在我必须对其进行跟踪并将其注册到更大的课程中以进行管理。

问题在于,复杂类可能会创建自己的新实例。因此,我必须在我的经理中检测到这个新创建。

另一个问题是经理不止一个。它们被用作会话管理器。每个都有一个初始的复杂对象。如果复杂对象实例化了它自己的一个新实例,那么只有优秀的管理者必须被警告。

下面是一个代码示例来说明我的问题:

class Foo:
    def create_another(self):
        # Do something
        return Foo()

class Manager:
    def __init__(self):
        init_object = SomeDecorator(Foo()) # I guess there will be a decorator
        self.objects = [init_objects]

m1 = Manager()
assert len(m1.objects) == 1

m1.objects[0].create_another()
assert len(m1.objects) == 2

m2 = Manager()
assert len(m1.objects) == 2
assert len(m2.objects) == 1

m1.objects[0].create_another()
assert len(m1.objects) == 3
assert len(m2.objects) == 1

m2.objects[0].create_another()
assert len(m1.objects) == 3
assert len(m2.objects) == 2

【问题讨论】:

  • TBH 我不太确定你在这里问什么...如果你问一些更具体的问题会有所帮助吗?
  • 类 Foo 是一个树节点,可以创建新节点作为新子节点。我想通过上下文(Manager)保存新节点的创建。Manager 和 Foo 之间没有逻辑链接,所以我认为编辑 Foo 类不好。 Manager 类用于加载/保存树并在我的架构中添加服务层。
  • 第二个断言应该是针对 m1 的吧?
  • 这很难说,因为你想要什么是模糊的,但这听起来像是电路组件架构和事件的一个很好的用例。见:circuits.readthedocs.org

标签: python decorator


【解决方案1】:

只是勾勒出一个想法(不完整/未经测试):

  1. 提供管理器作为参数:Foo.__init__(self, manager) 并将其存储为属性
  2. 您必须在Manager.__init__() 中致电init_object = Foo(self)
  3. 然后,您可以在create_another() 方法中使用有关经理的信息来
    • 正确实例化新实例
    • 修改Manager.objects-list(我会推荐一种方法而不是直接修改它)

【讨论】:

  • Foo 和 Manager 之间没有逻辑联系。我真的不想更改 Foo 类。使用装饰器不是问题
【解决方案2】:

如果您的Foo 对象一次只能由一位经理跟踪,则只需在调用create_another 时通知它即可完成。

示例代码:

class Foo:
    def __init__(self, manager=None):
        self.manager = manager

    def create_another(self):
        # do something
        foo = Foo(self.manager)
        if self.manager is not None:
            self.manager.notify_object_created(foo)
        return foo

class Manager:
    def __init__(self):
        init_object = SomeDecorator(Foo(self))
        self.objects = [init_object]

    def notify_object_created(self, foo):
        self.objects.append(foo)

阅读cmets后编辑:

如果你不想改变 Foo 类,另一种解决方案是动态装饰 Foo 的构造函数,通过跟踪它,将上述特性添加到它。

示例代码:

class Foo:
    def create_another(self):
        # do something
        return Foo()

class Manager:
    def __init__(self):
        self.objects = []
        self.track(Foo())

    def track(self, foo):
        def decorated_create_another():
            new_foo = foo._create_another()
            self.track(new_foo)
            return new_foo
        foo._create_another = foo.create_another
        foo.create_another = decorated_create_another
        self.objects.append(foo)

当然,这不会检查是否覆盖现有的 _create_another 方法、多次跟踪同一个 Foo 对象等...

【讨论】:

  • 事实上我的示例代码并不是我项目中的真实案例><.>create_another 不返回任何内容(实际上,知道操作成功是一个布尔值)。我猜装饰器重新定义了 Foo 对象的__init__ 或__new__。但我不知道如何
【解决方案3】:

这就是__new__ 的用途,不是吗?

https://stackoverflow.com/a/13054570/705086

【讨论】:

  • 这究竟是如何回答 OP 的问题的?
猜你喜欢
  • 2016-07-06
  • 1970-01-01
  • 2014-05-13
  • 2015-10-22
  • 1970-01-01
  • 2016-05-31
  • 2021-01-24
  • 1970-01-01
  • 2015-01-30
相关资源
最近更新 更多