python代码的层次结构_python:整个层次结构的子类

基于Mistermiyagi的例子,我的解决方案处于问题的底部。

我不知道怎样才能最好地表达这个标题。我的想法如下。我有一个带有一些实现的抽象基类。其中一些实现作为逻辑的一部分相互引用,简化如下:

import abc

# the abstract class

class X(abc.ABC):

@abc.abstractmethod

def f(self):

raise NotImplementedError()

# first implementation

class X1(X):

def f(self):

return 'X1'

# second implementation, using instance of first implementation

class X2(X):

def __init__(self):

self.x1 = X1()

def f(self):

return self.x1.f() + 'X2'

# demonstration

x = X2()

print(x.f()) # X1X2

print(x.x1.f()) # X1

现在我想在某个地方使用这些类,比如在另一个模块中。但是,我想添加一些额外的功能(例如函数

g

)到层次结构中的所有类。我可以把它添加到基类中

X

,但我希望将功能单独定义。例如,我可能想这样定义新功能:

class Y(X):

def g(self):

return self.f() + 'Y1'

这将创建另一个具有新功能的基类,但当然不会将其添加到现有实现中。

X1

X2

. 我得用钻石继承才能得到:

class Y1(X1, Y):

pass

class Y2(X2, Y):

pass

# now I can do this:

y = Y2()

print(y.g()) # X1X2Y1

以上工作正常,但仍有问题。在

X2.__init__

,的实例

X1

创建。为了让我的想法奏效,这必须成为

Y1

在里面

Y2.__init__

. 当然不是这样的:

print(y.x1.g()) # AttributeError: 'X1' object has no attribute 'g'

我想我要找的是一个转弯的方法

X

到一个抽象的元类中,这样它的实现就需要一个“base”参数来成为类,然后才可以实例化。然后在类中使用此参数以正确的基实例化其他实现。

使用基类中的新功能创建一个实例,如下所示:

class Y:

def g(self):

return self.f() + 'Y1'

X2(Y)()

这将导致一个对象等价于以下类的实例:

class X2_with_Y:

def __init__(self):

self.x1 = X1(Y)()

def f(self):

return self.x1.f() + 'X2'

def g(self):

return self.f() + 'Y1'

然而,我不知道如何创建一个这样做的元类。我想知道一个元类是否是正确的想法,如果是这样的话,如何去做。

解决方案

用Mistermyagi的例子,我可以得到一些我认为有用的东西。这种行为接近我的元类思想。

import abc

class X(abc.ABC):

base = object # default base class

@classmethod

def __class_getitem__(cls, base):

if cls.base == base:

# makes normal use of class possible

return cls

else:

# construct a new type using the given base class and also remember the attribute for future instantiations

name = f'{cls.__name__}[{base.__name__}]'

return type(name, (base, cls), {'base': base})

@abc.abstractmethod

def f(self):

raise NotImplementedError()

class X1(X):

def f(self):

return 'X1'

class X2(X):

def __init__(self):

# use the attribute here to get the right base for the other subclass

self.x1 = X1[self.base]()

def f(self):

return self.x1.f() + 'X2'

# just the wanted new functionality

class Y(X):

def g(self):

return self.f() + 'Y1'

用法如下:

# demonstration

y = X2[Y]()

print(y.g()) # X1X2Y1

print(y.x1.g()) # X1Y1

print(type(y)) #

# little peeve here: why is it not '__main__.X2[Y]'?

# the existing functionality also still works

x = X2()

print(x.f()) # X1X2

print(x.x1.f()) # X1

print(type(x)) #

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值