【发布时间】:2016-01-19 10:51:02
【问题描述】:
在 Python 3 中,您可以像这样创建类:
class foo:
def __init__(self, x):
self.x=x
def __call__(self, y):
self.x = self.x + 1
return (self.x, y)
然后可以将其用作具有如下状态的函子:
functor = foo(5)
x = 44354234
print('(1.1) ', functor(7))
print('(1.2) ', functor(8))
print('(1.2) ', functor(9))
实际上,我创建了一个返回函数的函数。然而,这第一个函数实际上是一个返回可调用对象的构造函数。恕我直言,这通过允许开发人员扩展类、添加方法等打开了一大堆蠕虫。此外,__init__ 中的代码以某种方式自然地先于__call__ 中的代码,因为它需要执行,那就是在类结构中不清楚。最后,Python 3 的“方式”建议在类上使用函数。
出于这个原因,我创建了一个类似的函数版本的类,它的样板代码更少,恕我直言,读起来更自然:
def bar(x):
def f(y):
nonlocal x
x = x + 1
return (x,y)
return f
functor2 = bar(5)
x = 345234234
print('(2.1) ', functor2(7))
print('(2.2) ', functor2(8))
print('(2.3) ', functor2(9))
但是,它使用nonlocal,并且由于我没有想到的原因可能不直观。第二种方法是好的做法,还是有危险的挖坑?在 Python 3 中应该首选哪个?特别是因为我没有使用nonlocal的经验。
【问题讨论】:
-
“恕我直言,这通过允许开发人员扩展类打开了一罐蠕虫”——这是一件坏事,为什么?另外,我不确定问题是什么。哪个会更受欢迎?使用更有意义的东西。
-
"此外,init 中的代码在某种程度上自然地先于 call 中的代码,因为它需要执行,这在内部并不清楚类结构。” =>它非常清楚初始化器将在调用
__call__之前被执行。 -
“最后,Python 3 的‘方式’建议在类上使用函数”:章节和诗句好吗? “Python 方式”——无论 FWIW 版本如何——是使用对手头任务有意义的构造。在这种情况下,两者都有意义,但第一个允许子类化和易于检查。
-
@brunodesthuilliers 我指的是这个:github.com/amontalenti/elements-of-python-style/blob/master/… - 我关于类的观点是,它们 (1) 有可能成为神级,因为它们通过属性和方法进行扩展,并且 (2) 不要描述一个自然的输入输出流程,因为不清楚哪些属性是在哪些方法中读取或写入的。
-
@brunodesthuilliers 是的,init 显然在 call 之前,但我认为类代码不一定强调这一点,尤其是当有更多方法时而不仅仅是打电话。诚然,这是非常值得商榷的。
标签: python python-3.x coding-style