我已经考虑了好几个小时了。我有一类最终需要(但将初始化而没有)一些关键属性的类。此类的子类需要不同的属性。

如果有帮助,这是半边数据结构中Verts,Edges和Faces的基础MeshElement类。

通常,我需要创建一个与另一个实例相似但不相同的距离,因此,我有以下borrow_b这样的方法将属性从一个实例复制到另一个实例。

我无法提出一个borrow_b构造函数,其中a)保留/复制了init的类型提示,b)可以由具有不同必需属性的子类继承。

这是我最聪明的想法,但它违反了“修改对象的方法返回无”的规则。

class AB:

    def __init__(self, a: Optional[int] = None, b: Optional[int] = None):
        if a is not None:
            self.a = a
        if b is not None:
            self.b = b

    def borrow_b(self, other):
        self.b = other.b # already type hinted when other was initialized
        return self

# >>> one_two = AB(1, 2)
# >>> six_two = AB(6).borrow_b(one_two)


我当然知道这可以分为两行:

six_two = AB(6)
six_two.borrow_b(one_two)


...并允许borrow_b返回None,但是我喜欢第一个看起来更像构造函数,而且我不相信第一个不是“ Pythonic”。

当然,要为更好的解决方案做好准备。

FWIW,

six_two = AB(6, six_two.b)


...不是一个“可行的”解决方案,因为并非所有我想复制的属性都是“必需的”。我通常想复制一些必需的参数,以及通常但不是必须附加到网格元素(颜色,uv,硬度等)的其他标记的类型。

最佳答案

使用类方法来实现备用构造函数。对象的目的是在多个方法调用或函数边界之间保持状态。创建仅在一个作用域中使用并立即丢弃的对象,这表明您只需要一个带有适当参数的函数。

class AB:

    def __init__(self, a: Optional[int] = None, b: Optional[int] = None):
        if a is not None:
            self.a = a
        if b is not None:
            self.b = b

    @classmethod
    def borrow_b(cls, o1: AB, o2: AB):
        return cls(o1.a, o2.b)

one_two = AB(1, 2)
six = AB(6)
six_two = AB.borrow_b(one_two, six)


是的,six似乎仅是为了初始化six_two而创建的,但可能由于其他原因而存在。否则,您可以定义一个类方法,该方法专门使用一个对象和任意一组其他参数来覆盖“原型”。就像是

@classmethod
def make_from_prototype(cls, prototype, **kwargs):
    new_obj = cls(prototype.a, prototype.b)
    for attr, value in kwargs:
        setattr(new_obj, attr, value)
    return new_obj

...

one_two = AB(1,2)
six_two = AB.make_from_prototype(one_two, b=6)


一个缺点是make_from_prototype绕过类型提示,因为**kwargs可以接受任意一组关键字参数。最好
用作私有类方法,该类方法仅用作专用类方法(例如borrow_b)的基础实现:

@classmethod
def _make_from_prototype(cls, prototype: AB, **kwargs):
    # Same definition as above

@classmethod
def borrow_b(cls, o1: AB, o2:AB):
    return cls._make_from_prototype(o1, b=o2.b)

关于python - my_instance = MyClass(a,b).my_method(c)是可接受的(Pythonic)模式吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53108988/

10-13 09:36