我想知道在python中部分初始化对象属性是否是functools.partial
的有效用例。假设我有一个基类A
,它有三个对象级属性(attr1
、attr2
、attr3
(:
class A:
def __init__(self, attr1, attr2, attr3):
self.attr1 = attr1
self.attr2 = attr2
self.attr3 = attr3
def do_something(self):
pass
现在,我想基于这个基类创建对象,其中一个属性(比如attr1
(始终是固定的,但其他两个属性可能会有所不同。我可以想到的一种方法是定义一个从基类A
继承的类,该类具有在初始化过程中使用的固定类级别属性,类似于以下内容:
class PartialA(A):
attr1="foo" # fixed class-level attribute
def __init__(self, attr2, attr3):
super().__init__(self.attr1, attr2, attr3)
然后,我可以通过只指定不同的对象级别属性来创建对象,比如:
partial_a = PartialA(attr2="baz", attr3="baz")
实现类似行为的另一种方法是使用functools.partial
部分初始化基类A
的__init__
,然后从中创建对象:
from functools import partial
PartialA = partial(A, attr1="foo")
partial_a = PartialA(attr2="bar", attr3="baz")
这两种方法是否同样有效,或者以这种方式使用functools.partial
的方法是否存在我目前不知道的危险/缺点?很乐意听取您的意见!
我尝试了上面概述的两种方法,到目前为止,我还看不出在行为方面有什么不同。但很可能有一些我目前还不知道的理由支持一个而不是另一个。
在这两种情况下,基本上都是定义工厂函数来创建A
的实例。我将采用第三种方法,一种使用类方法实现的替代构造函数。
class A:
def __init__(self, attr1, attr2, attr3):
self.attr1 = attr1
self.attr2 = attr2
self.attr3 = attr3
@classmethod
def with_foo(cls, attr2, attr3):
return cls("foo", attr2, attr3)
def do_something(self):
pass
a = A.with_foo("bar", "baz") # a = A("foo", "bar", "baz")
这与您的两次尝试之间的一个主要区别是,您不能覆盖A.with_foo
如何设置第一个属性。(使用该类,您可以在创建实例之前简单地重新定义PartialA.attr1
,另外,您现在有了一个不需要存在的奇怪的第二个类。使用partial
,您仍然可以将自己的值attr1
作为关键字参数传递。(