在类定义之后立即实例化python对象
在大型python项目(openerp)中,我多次遇到以下模式: 在模块中,定义了一个类及其方法。然后,在同一模块中,在类定义之后立即实例化该类的实例,然后从其他模块调用该实例在类定义之后立即实例化python对象,python,openerp,instantiation,python-module,Python,Openerp,Instantiation,Python Module,在大型python项目(openerp)中,我多次遇到以下模式: 在模块中,定义了一个类及其方法。然后,在同一模块中,在类定义之后立即实例化该类的实例,然后从其他模块调用该实例 # in module_A.py: class ClassA(object): def __init__(self, default="Hello world!"): self.default = default def my_method(self, data):
# in module_A.py:
class ClassA(object):
def __init__(self, default="Hello world!"):
self.default = default
def my_method(self, data):
print self.default
print data
object_a = ClassA()
在我看来,将方法定义为模块函数更简单,没有类查找重载:
# in module_B.py:
default = "Hello world!"
def my_method(data):
print default
print data
从其他模块来看,用法非常相似:
from module_a import object_a as prefix
prefix.my_method("I'm so objective!")
与:
import module_b as prefix
prefix.my_method("I'm so modular!")
是否有理由选择A模式而不是B模式?或者模式B更像Python?除了其他好处之外,使用类允许您在实例上使用内省,这是函数所不能做到的
更一般地说,这两种方法都是“pythonic”。使用另一个取决于项目的类型(小/大,有/没有GUI,…)有时,您希望不同的客户端能够使用不同设置的模块,这样它们就不会相互冲突。例如,Python的模块提供了一系列随机数生成函数,这些函数实际上是隐藏的
random
实例的绑定方法。大多数用户并不太在意什么算法生成了他们的随机数,也不在乎其他请求随机数的模块是否会改变序列。但是,真正关心的用户可以获得自己的Random
对象,并生成随机数序列,这些序列不会受到其他请求随机数的模块的影响
有时,现在是全球性的东西可能并不总是全球性的。例如,如果您在行星级RTS上工作,您可能有一个带有一个实例的Planet
类,因为战斗只发生在一个行星上。然而,你不想排除建造类似于行星毁灭的东西的可能性,因为战争延伸到整个太阳系,并将灭绝事件小行星作为超级武器投放。如果您去掉了Planet
类,并将其方法和属性模块设置为级别,那么以后要返回并添加更多的Planet将会困难得多
有时候,让对象来做事情比让模块来做事情更容易理解。例如,假设模块joebob
定义了两个对象evil\u overlard\u bob
和good\u guy\u joe
class Bob(object):
def slaughter_everything(self):
print "Muahahaha! Die for my amusement!"
class Joe(object):
def stop_bob(self):
print "I won't let you hurt those innocents!"
evil_overlord_bob = Bob()
good_guy_joe = Joe()
假设鲍勃和乔是非常独特的人。你想创建另一个像Bob或Joe这样的对象是不可想象的。在这种情况下,您可以将slaught\u everything
和stop\u bob
移动到模块级别,并完全删除bob和Joe类和对象。然而,那你就要写作了
joebob.slaughter_everything()
joebob.stop_bob()
如果你能说的话,事情就更清楚了
evil_overlord_bob.slaughter_everything()
good_guy_joe.stop_bob()
即使你永远不需要实例化Bob同样邪恶的孪生兄弟greg_the_Fleshipper也不会回答你的问题,但这可能会让你感兴趣。正如你提到的OpenERP,这是为非OpenERP模型但不为OpenERP模型执行此操作的类找到的。在OpenERP<7中,您确实需要自己实例化每个模型,但是OpenERP管理一个您应该使用self.pool.get访问的单例实例。AdrianWell,你可以对模块进行内省,这在对象内省的模式B中是等效的。所以你的主要论点是类比模块更可重用。另一方面,Josay链接的视频(对问题的评论)认为这是一种不成熟的实现形式。goodguy/badguy示例可以很容易地以模式B风格编写为两个单独的模块。@QuantMetropolis:我不知道这些类在您的情况下是否是一个好主意。我不知道你在看什么代码,也不知道系统的设计。我只是举了一些例子,在这些例子中,您可能更喜欢一个具有单个实例的类,而不是模块级的函数和状态。虽然您可以将Bob和Joe实现为两个模块,但它们在逻辑上是紧密组合在一起的。将它们放在单独的模块中需要两个导入,这对于一个依赖项来说更有意义,而且用
表示Bob比用
表示Bob更难理解。另外,您可能在bob
和joe
模块中有一个循环导入,没有人希望这样。