本周comp.lang.python语言,一段“有趣”的代码被史蒂文·达普拉诺作为家庭作业问题的笑话答案。在这里:
class MultiplierFactory(object):
def __init__(self, factor=1):
self.__factor = factor
@property
def factor(self):
return getattr(self, '_%s__factor' % self.__class__.__name__)
def __call__(self, factor=None):
if not factor is not None is True:
factor = self.factor
class Multiplier(object):
def __init__(self, factor=None):
self.__factor = factor
@property
def factor(self):
return getattr(self,
'_%s__factor' % self.__class__.__name__)
def __call__(self, n):
return self.factor*n
Multiplier.__init__.im_func.func_defaults = (factor,)
return Multiplier(factor)
twice = MultiplierFactory(2)()
我们知道twice
相当于答案:
def twice(x):
return 2*x
从Multiplier
和MultiplierFactory
这两个名称中,我们了解了代码的作用,但我们不确定确切的内部结构。让我们先简化一下。你知道吗
if not factor is not None is True:
factor = self.factor
not factor is not None is True
等价于not factor is not None
,也就是factor is None
。结果:
if factor is None:
factor = self.factor
直到现在,这很容易:)
另一个有趣的点是好奇的factor
访问器。你知道吗
def factor(self):
return getattr(self, '_%s__factor' % self.__class__.__name__)
在初始化MultiplierFactory
期间,设置self.__factor
。但是后来,代码访问self.factor
。你知道吗
看来:
getattr(self, '_%s__factor' % self.__class__.__name__)
完全是“self.__factor
”。你知道吗
我们是否可以始终以这种方式访问属性?
def mygetattr(self, attr):
return getattr(self, '_%s%s' % (self.__class__.__name__, attr))
总之,在这一点上,这里是简化的代码:
class MultiplierFactory(object):
def __init__(self, factor=1):
self.factor = factor
def __call__(self, factor=None):
if factor is None:
factor = self.factor
class Multiplier(object):
def __init__(self, factor=None):
self.factor = factor
def __call__(self, n):
return self.factor*n
Multiplier.__init__.im_func.func_defaults = (factor,)
return Multiplier(factor)
twice = MultiplierFactory(2)()
代码现在几乎是干净的。唯一令人费解的可能是:
Multiplier.__init__.im_func.func_defaults = (factor,)
里面有什么?我查看了datamodel doc,发现func_defaults
是“一个元组,其中包含那些具有默认值的参数的默认参数值,或者如果没有参数具有默认值,则没有参数”。我们只是在这里更改factor
参数的默认值吗?结果代码将是:
class MultiplierFactory(object):
def __init__(self, factor=1):
self.factor = factor
def __call__(self, factor=None):
if factor is None:
factor = self.factor
class Multiplier(object):
def __init__(self, innerfactor=factor):
self.factor = innerfactor
def __call__(self, n):
return self.factor*n
return Multiplier(factor)
twice = MultiplierFactory(2)()
这意味着动态设置默认值只是无用的杂音,因为没有默认参数就永远不会调用Multiplier
,right?你知道吗
我们可以把它简化为:
class MultiplierFactory(object):
def __init__(self, factor=1):
self.factor = factor
def __call__(self, factor=None):
if factor is None:
factor = self.factor
def my_multiplier(n):
return factor*n
return my_multiplier
twice = MultiplierFactory(2)() # similar to MultiplierFactory()(2)
对吗?你知道吗
对于那些急于“这不是一个真正的问题”的人来说。。。再读一遍,我的问题用粗体+斜体
问题1。我们可以一直以这种方式访问属性吗?你知道吗
答:没有。只有那些属性以双下划线开头。它们以这种方式被混淆,以防止类外部的意外访问/重写。你知道吗
问题2:我们只是在这里更改
__init__
中因子参数的默认值吗?你知道吗A:是的。你知道吗
问题2:是吗?你知道吗
是的。你知道吗
相关问题 更多 >
编程相关推荐