我有一个类,可以通过使用类方法的替代构造函数来构造。你知道吗
class A:
def __init__(self, a, b):
self.a = a
self.b = b
@classmethod
def empty(cls, b):
return cls( 0 , b)
所以我们不必像A()
那样构建A
,我现在也可以做A.empty()
。你知道吗
为了方便用户,我想进一步扩展这个empty
方法,这样我就可以通过A.empty()
以及更专业但密切相关的A.empty.typeI()
和A.empty.typeII()
初始化A
。你知道吗
我天真的做法并没有达到我的目的:
class A:
def __init__(self, a, b):
self.a = a
self.b = b
@classmethod
def empty(cls, b):
def TypeI(b):
return cls( 0 , b-1)
def TypeII(b):
return cls( 0 , b-2)
return cls( 0 , b)
有人能告诉我怎么做吗(或者至少能说服我为什么那会是个糟糕的主意)。我想强调的是,对于用法,我认为这样的方法对于用户来说非常方便和清晰,因为函数是直观地分组的。你知道吗
您可以通过使
Empty
成为A
的嵌套类而不是类方法来实现所需的功能。最重要的是,它提供了一个方便的名称空间—从不创建它的实例—在其中放置各种可选构造函数,并且可以轻松地进行扩展。你知道吗通常最好有统一的类接口,这意味着不同的用法应该相互一致。我认为
A.empty()
和A.empty.type1()
是不一致的,因为前缀A.empty
在它们各自的意思是不同的。你知道吗更好的接口是:
或:
您不能这样做,因为
A.empty.something
需要将底层方法对象绑定到该类型,这样您就可以实际调用它。Python不会这么做,因为类型的成员是empty
,而不是TypeI
。你知道吗所以您需要做的是在您的类型中有一些返回绑定类方法的对象
empty
(例如SimpleNamespace)。问题是,当我们用class
结构定义类型时,我们还不能访问它。所以我们不能访问它的成员来设置这样的对象。相反,我们必须事后再做:现在,您可以访问该成员的项并获取绑定方法:
当然,那可不是那么漂亮。理想情况下,我们希望在定义类型时设置它。我们可以使用元类来解决这个问题,但实际上我们可以使用类装饰器轻松地解决这个问题。例如这个:
神奇的是,它起作用了:
既然我们已经成功了,当然我们应该讨论一下这是否真的是你想做的事情。我的意见是你不应该这样做。你已经从所做的努力中看到了这不是Python通常做的事情。这已经是一个好迹象表明你不应该这么做。Explicit is better than implicit,所以最好只要求用户键入类方法的全名。我上面的例子当然是以一种
A.empty.empty_a
比A.empty_a
更长的方式构建的。但即使是你的名字,也没有理由让它不能只是一个下划线而不是一个点。你知道吗而且,您可以简单地在一个方法中添加多个默认路径。提供默认参数值,或者使用合理的回退,您可能不需要很多类方法来创建类型的替代版本。你知道吗
相关问题 更多 >
编程相关推荐