Python:创建超级对象的陷阱
我们发现,在大多数类中都存在一组属性(所有属性都不会在运行时更改并从环境中提取)。我试着四处搜索这个词,但不幸的是“object”是一个非常常见的词 如果我执行以下操作,会导致什么类型的问题: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):
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