Python - 类变量 vs 值字典

4
假设我有一个类,表示一个具有许多属性(例如字符串和整数等简单数据类型)的对象。应该将它们表示为实例变量,还是更好地遵循“Pythonic”的方式,将它们放入字典中呢?
例如:
class FruitBasket:
    def __init__(self,apples, oranges, bananas, pears): #number of apples, oranges etc...
        self.apples = apples
        self.oranges = oranges
        self.bananas = bananas
        self.pears = pears



class FruitBasket:
    def __init__(self, fruits): #fruits is a dictionary
        self.fruits = fruits

这取决于您期望代码在未来如何更改。使用字典解决方案可以更轻松地扩展任意新类型的水果。 - pts
4个回答

6
我的一般哲学是,如果项的集合更或多或少是固定的,请使用属性;如果集合可能会根据需要随意更改,则请使用字典。如果你的FruitBasket专门用于包含苹果、橙子、香蕉和梨子,那么请使用属性。如果它可以包含任何其他随机物品(例如,有时您可能会加入菠萝或覆盆子),请使用字典。
一个原因可以在您的示例代码中看到。如果使用属性,您必须在代码中明确指定每个属性(例如,self.pears)。此外,您经常会像在这里做的那样,显式将每个项作为参数传递给__init__。如果稍后决定添加新水果,则显然无法正常工作。您可以继续向__init__添加更多参数,但这很快变得笨重。
此外,如果您具有固定的项目集,您可能会单独访问它们。也就是说,如果您知道只有苹果、橙子、香蕉和梨子,那么您可以按名称直接访问它们,就像在此处一样(self.apples、self.oranges等)。如果您提前不知道篮子里可能有什么水果,您通常会通过对其进行迭代来处理它们。非常容易迭代字典的项。相比之下,迭代对象的属性充满了危险,因为您无法轻松区分包含对象“有关”的数据的属性(例如self.pears)和与对象本身的结构相关的属性(例如self.__init__、self.basketColor、self.basketSize等)。
简而言之,如果您提前不知道篮子里会有什么,那么您将希望迭代其内容,如果要迭代某个内容,则最好使用专为包含而设计的类型(例如列表或字典),因为这些类型清晰地将容器与其内容分开。

如果这些值是常量怎么办? 假设我的类代表一个相机,它需要获取相机的属性(镜头类型、百万像素、公司等)。把它们保存在字典中会更有意义吧? - matanc1
@Shookie:这不是一条严格的规则。你当然可以使用字典。但是,如果您的相机始终具有完全相同的属性,而没有其他属性,那么将它们作为属性会更有意义。 - BrenBarn

0

这取决于你打算用它做什么。字典更灵活,因为可以更容易地扩展新的水果,你可以迭代获取它们所有的值。将水果表示为成员变量可以节省一些输入,但是你必须硬编码所有对它们的访问。

存在一个中间地带,就是使用模式来同步两者。这里有一些关于如何实现它的讨论。

在你写另一个类之前,请记住:停止写类。


0

这个问题和非常相似的问题已经被问过很多次了,而且有各种不同的AttrDict实现。

然而,你应该问问自己是否有任何理由不使用字典。如果没有,那么显然符合Python风格的做法是使用字典。一个没有方法的类可能根本就不应该是一个类。你还应该考虑到并非所有有效的字典键都是有效的属性名。


0

您可能想要使用字典,或者您可以使用新的Python 3.4枚举!如果应该是枚举。https://docs.python.org/3/library/enum.html

from enum import Enum
animal = Enum('Animal', 'ant bee cat dog')
animal.ant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接