python - 玩转对象创建

标签 python oop inheritance factory subclassing

我有两个带有方法 foo 的类:

Foo = type('Foo', (object,), {'foo': lambda s: 'Foo method'})
Bar = type('Bar', (object,), {'foo': lambda s: 'Bar method'})

我还有一些其他类,我需要根据参数将其子类化为上述类之一。

我的解决方案:

class Subject(object):
    def __new__(cls, key):
        base = (Foo if key else Bar)

        name = cls.__name__ + base.__name__
        dict_ = dict(cls.__dict__.items() + base.__dict__.items())
        bases = (base, cls)

        t = type(name, bases, dict_)
        return base.__new__(t)

    def bar(self):
        return 'Subject method'

测试:

print(Subject(True).foo(), Subject(True).bar())
print(Subject(False).foo(), Subject(False).bar())

输出:

('Foo method', 'Subject method')
('Bar method', 'Subject method')

这个解决方案足够安全吗?或者我需要了解更多信息?有没有更多的Pythonic方法来做这种不规则的事情?

最佳答案

我想大多数人看到上面的代码都会推荐使用组合而不是继承。主题将定义一个 foo 方法,该方法根据 bool 值分派(dispatch)到正确的类。

或者,您可以根据需要使用工厂函数来创建 Foo 或 Bar。

def subject(selector):
     'Factory function that chooses between Foo and Bar'
     return Foo() if selector else Bar()

如果需要,让 Foo 和 Bar 都继承自公共(public)类,以便工厂函数始终返回公共(public)类的子类的实例。

关于python - 玩转对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7959883/

相关文章:

python - 什么决定了 CNN 末端密集层的输入维度

java - 获取当前类(class)的引用

C++虚拟运算符删除?

inheritance - 我应该继承 List<T> 还是将其作为属性?

python - pipenv 始终无法安装 psycopg2

python - 创建可变数量的变量并从列表中填充它们

python - 如何根据日期对日期进行分组?

php - 跨站点伪造 (CSRF) 和公共(public)应用程序接口(interface)

python - 这是面向对象语言的正常行为吗?

c++ - 循环包含和前向声明类