Python class 和方法 - 访问和更改属性的最佳实践?

Python class and methods - best practice for accessing and altering attributes?

TLDR:访问和更改 class 实例属性的最佳做法是什么?

假设我们有一个 class 来生成一个对象,该对象旨在保存有关产品的数据(例如,可能是产品主数据集)。

class StoreProduct(object):

    def __init__(self,ProductID,ProductPrice,ProductDescription):
        self.ProductID = ProductID
        self.ProductPrice = ProductPrice
        self.ProductDescription = ProductDescription


    def ChangeProductPrice(self, newProductPrice):
        self.ProductPrice = newProductPrice

我们还有另一个 class 可以用来访问由 StoreProduct() 生成的那些实例,以及进行调整/更改的方法。

class ChangeProductData(object):

    def __init__(self):
        pass
    @staticmethod
    def ChangeProductObjectPrice(newProductPrice,ProductObject):

        ProductObject.ProductPrice = newProductPrice

因此我们生成一个名为 Product1 的实例:

Product1 = StoreProduct(
    ProductID="Product1",
    ProductPrice=4,
    ProductDescription="A nice lamp"
)

读取 and/or 改变 class 实例的最佳编码实践是什么?

如果我想更改产品 1 中的某个属性(在本例中为价格),这种情况通常是可以接受的,还是代码错误?

方法一

ChangeProductData().ChangeProductObjectPrice(8,Product1)

或者这是首选的方式吗?

方法二

Product1.ChangeProductPrice(2)

什么时候会有例外?

虽然以上是简化的情况,但我目前阅读的内容似乎表明方法 2 可能是更好的做法。但是,方法 1 是否会在将来提供更大的灵活性(例如,如果您需要更改方法的工作方式或添加新方法)。

我也一直在阅读 getattr() 和 setattr(),但人们似乎对它是否比使用点更好(例如 Product1.ProductPrice 来获取价格)感到困惑。

绝对是方法 2。正如 @user2357112 提到的,方法 1 没有意义。 正如您正确指出的那样,这是一个简单的场景,pythonic 方式将使用 property

class StoreProduct(object):  # minor: please notice the PEP styling
    def __init__(self, product_price):
        self._price = produce_price
        # other attributes, omitted for brevity

    @property
    def product_price(self):  # pythonic getter
        return self._price

    @product_price.setter
    def product_price(self, new_price):  # python setter
        # you could do any custom validation before setting
        self._price = new_price

来到

的问题

I'm specifically tackling the issue of whether accessing and altering an class' attribute with another class is a big no-no.

  • 访问:这里可以访问。事实上,许多严重依赖组合的设计模式都是这样做的。例如,adapterstrategydecoratorcommand 等模式

  • 改变:您希望拥有该属性的 class 负责 "altering"。外国 class 只应 请求更改

P.S。这有点像 CQRS(命令查询责任分离)模式