Python:创建超级对象的陷阱

Python:创建超级对象的陷阱,python,python-2.7,Python,Python 2.7,我们发现,在大多数类中都存在一组属性(所有属性都不会在运行时更改并从环境中提取)。我试着四处搜索这个词,但不幸的是“object”是一个非常常见的词 如果我执行以下操作,会导致什么类型的问题: class MasterObjectv2(object): UNIQUE_KEY = getUniqueKey() #other properties for all objects in our system 还是这样更好: class MasterObject(object):

我们发现,在大多数类中都存在一组属性(所有属性都不会在运行时更改并从环境中提取)。我试着四处搜索这个词,但不幸的是“object”是一个非常常见的词

如果我执行以下操作,会导致什么类型的问题:

class MasterObjectv2(object):
     UNIQUE_KEY = getUniqueKey()
     #other properties for all objects in our system
还是这样更好:

class MasterObject(object):
    def __init__(self):
        object.__init__(self)
        #other properties for all objects in our system
        self.getUniqueKey()
或选择3

# is that its a really dumb idea to do this.
我正在考虑做第一个,因为我不必担心有人没有在MasterObject上调用init

显然,我们班将从

class Test(object):
   def __init__(self): 
        self.UNIQUE_KEY = getUniqueKey()


编辑

这些答案不能回答我的问题。我不是问我应该做什么,我是问如果我们走这条路,会有什么副作用/需要考虑的事情

我正在考虑使用一个environment.*类型的类,但我首先想知道如果我走另一条路,可能会有什么副作用


我不想把这变成一场作文与继承的辩论……;)

在实际的类中,您真的需要这些属性吗?听起来像是将它们保存在某个“配置对象”中,而仅仅从类中访问它是一个更健壮的想法

AFAIU,对于隐含is-a关系的情况,您更愿意严格地保留继承,而在您的情况下,这是不正确的。

如果属性是静态的,请使用选项1。由于属性是类的一个属性,并且不会在实例之间更改,因此这似乎是正确的选择。使用选项#1不会导致任何问题(假设类的实现与测试类似)

然后,您的测试类可以按如下方式实现:

class Test(MasterObject):
    pass

一旦从环境中获取属性,所有这些类的属性值是否都相同?如果是这样的话,您可能最好只在模块级别保留这些环境属性的
dict
。(或者,按照其他人的建议,使用模块填充和存储环境变量。)


如果没有,我的建议是使用创建一个类方法,在第一次为每个类调用
\uuuu init\uuuu
时,您可以使用该方法填充类中环境变量的字典;例如定义

class Master(object):
    def __new__(klass, *args, **kwargs):
        self = object.__new__(klass)
        self.attribute1 = ...
        self.attribute2 = ...
        return self
在派生类中最终定义的
\uuuuuuuu init\uuuuuuuuuu
启动之前,执行
\uuuuuuuuu new\uuuuuuuuuu
中的代码(因此,派生类是否不调用
Master.\uuuuuuuuuu init\uuuuuuuuuuuuuuu(self)
)。您可以使用
\uuuu new\uuuu
在开始
\uuuu init\uuuu
之前在实例中设置一些属性


在您的情况下,这样做是否合理在很大程度上取决于您没有提供的详细信息。

是的,我们需要类中的这些信息,出于代码能力/可读性的原因,我们希望它们包含在类中。我不想把这变成一场合成与继承的辩论。@Nix:嗯,那么选项3;-)你的观点已经被注意到了,我想我需要考虑的一件事是由于继承而浪费的内存,因为我们确实关心内存消耗。只是不断地编写同一组通用代码是非常烦人的。@Nix:如果每个实例开始读取环境,不仅会消耗内存,还会影响性能。当然,您可以将其设置为延迟读取(因此只有第一次读取可以执行某些操作,其他读取是免费的),但这与使用env/config对象类似。除此之外,您当然可以按照您提出的方式使用继承-它会起作用,但我认为这是对语言功能的滥用,因为它不是设计用来做的。这些属性是否因类而异?我们有一个多进程的系统,但一旦进程启动,我们就会读入(config、env等)中的env变量不会改变。为什么他们需要成为班级成员?例如,为什么不能说
环境.UNIQUE\u KEY
而不是
self.UNIQUE\u KEY
?其中,
environment
是您在其他模块中创建并导入的某个模块。或者,对于您创建的每个对象,这些键是否不同?因为如果每次调用
getUniqueKey
时返回不同的值,则选项1和2的结果会非常不同。
class Test(MasterObject):
    pass
class Master(object):
    def __new__(klass, *args, **kwargs):
        self = object.__new__(klass)
        self.attribute1 = ...
        self.attribute2 = ...
        return self