在python中使用functools.partial部分初始化对象属性



我想知道在python中部分初始化对象属性是否是functools.partial的有效用例。假设我有一个基类A,它有三个对象级属性(attr1attr2attr3(:

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作为关键字参数传递。(

最新更新