首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python类是否有将其实现委托给另一个类的模式?

python类是否有将其实现委托给另一个类的模式?
EN

Stack Overflow用户
提问于 2020-04-21 02:24:36
回答 1查看 34关注 0票数 0

我为一个可能是基本问题的问题道歉。我是一名C++程序员,对python比较陌生。

我有一个python类,它的行为很大程度上依赖于它的一个构造函数参数:

代码语言:javascript
复制
    class MyClass():
       def __init__(self, some_arg):
          self.some_arg = some_arg
          ...

       def abcd(self):
          if self.some_arg == 1:
             ...
          else:
             ...

       def efgh(self):
          if self.some_arg == 1:
             ...
          else:
             ...

我想将其重构为两个具有不同some_arg值的类。当然,最直接的方法是有两个类(可能有一个公共基类),然后让工厂函数选择实例化哪一个。大致是这样的:

代码语言:javascript
复制
   def MyClassSomeArg1():
      def __init__(self):
         ...

      def abcd(self):
         ...

      def efgh(self):
         ...

   def MyClassSomeArgNot1():
      def __init__(self):
         ...

      def abcd(self):
         ...

      def efgh(self):
         ...

   def buildMyClass(some_arg):
      if some_arg == 1:
        return MyClassSomeArg1()
      else:
        return MyClassSomeArgNot1()

我相信那会工作得很好。问题是我不想更改客户端代码。客户端期望使用some_arg的构造函数参数实例化"MyClass“类的对象。有没有一种好的方法可以在不改变客户端代码的情况下进行重构呢?

我尝试过使用实现层次结构: MyClassImpl作为基类,带有子类MyClassImplSomeArg1和MyClassImplSomeArgNot1。然后,MyClass本身就变得基本上是空的:

代码语言:javascript
复制
class MyClass():

   def __init__(self, some_arg):
      if some_arg == 1:
         self._impl = MyClassImplSomeArg1()
      else:
         self._impl = MyClassImplSomeArgNone1()

   def __getattr__(self, a):
      # For performance, I could store this in self so it doesn't need to be looked up each time
      return getattr(self._impl, a)

这基本上是可行的,但似乎不是最直接的事情。首先,像__str__和__eq__这样的神奇方法似乎没有通过__getattr__机制进行委托,我不知道为什么。不过,我自己编写委托方法并不难。此外,这会使pydoc感到困惑(它无法看到委托的属性),我不确定如何解决这个问题。

有没有一些糖可以让这个授权方案很好地发挥作用?或者委派是处理这样的问题的最佳方式吗?

谢谢,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-21 02:41:40

您可以覆盖__new__函数并返回一个基于some_arg的子类。这是实现工厂的常见模式

代码语言:javascript
复制
class MyClassImplSomeArg1:
    pass

class MyClassImplSomeArgNone1:
    pass

class MyClass:
    def __new__(cls, some_arg):
        if some_arg:
            return MyClassImplSomeArg1()
        else:
            return MyClassImplSomeArgNone1()

assert isinstance(MyClass(some_arg=True), (MyClassImplSomeArg1,))
assert isinstance(MyClass(some_arg=False), (MyClassImplSomeArgNone1,))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61329394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档