Python 在类变量中创建对类的引用,并在_init中实例化它们__
我最近在Python中看到了很多以下模式:Python 在类变量中创建对类的引用,并在_init中实例化它们__,python,oop,Python,Oop,我最近在Python中看到了很多以下模式: class Foo: pass class Bar: foo_class = Foo def __init__(self): self.foo = self.foo_class() 据我所知,Bar类首先创建一个对Foo类的引用,作为类变量Foo\u类,然后在\uu init\uu中创建Foo的实例。与其直接在中实例化Foo,它还有什么好处吗 class Foo: pass class Bar: def
class Foo: pass
class Bar:
foo_class = Foo
def __init__(self):
self.foo = self.foo_class()
据我所知,Bar
类首先创建一个对Foo
类的引用,作为类变量Foo\u类
,然后在\uu init\uu
中创建Foo
的实例。与其直接在中实例化Foo
,它还有什么好处吗
class Foo: pass
class Bar:
def __init__(self):
self.foo = Foo()
有一些小的好处,因为您不再在无法更改的地方硬编码对Foo
的引用。在第一个示例中,如果希望Bar
的后续实例使用foo
以外的内容,可以更改Bar.foo\u类的值。在第二个例子中,没有简单的方法可以做到这一点
然而,一个更好的方法是参数化\uuuu init\uuu
本身,以接受一个类来代替它。class属性将只是一个默认值:
class Bar:
foo_class = Foo
def __init__(self, foo_class=None):
if foo_class is None:
foo_class = self.foo_class
self.foo = foo_class()
如果foo_class
仅由\uuuu init\uuuu
使用,则可以完全取消class属性,并为参数设置默认值
class Bar:
def __init__(self, foo_class=Foo):
self.foo = foo_class()
(如果Bar.foo\u类
在\uu init\uuuu\ucode>之外使用,您可能需要确保使用可能不同的类创建的self.foo
没有任何问题。)我一直在理解设计模式方面有困难,但这是工厂模式的应用,不是吗?有人可以确认吗?通过将类ref分配给变量,我们可以轻松地更改所需的类。变化恰巧发生在其中place@Aran-可能是菲?我在看,似乎很清楚,make_room
可能只是对类的引用,而不是抽象方法。@chepner是的,这也是我的思路。谢谢,解释清楚了。非常感谢。尽管这让我思考——如果你不打算在将来的某个地方更改Bar.foo_类
,那么这样做真的没有意义吗?YAGNI@taurijuhkam在生产使用中,没有。不过,对于测试来说,它提供了一个方便的钩子,可以用纯值替换具有效果的内容(如数据库连接、I/O等)。例如,self.foo
可能是生产中的一个文件句柄,但对于测试,您可能需要一个瞬间的StringIO
。能够用提供静态数据的类替换打开文件的类将使测试更容易理解。感谢您提供了一个用例,使其清晰明了:想象一下在测试中您可能希望在哪里使用mock.patch
,并设计成您不需要它:)