和我一起去那个模糊的乘数工厂

2024-09-30 22:15:13 发布

您现在位置:Python中文网/ 问答频道 /正文

本周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

MultiplierMultiplierFactory这两个名称中,我们了解了代码的作用,但我们不确定确切的内部结构。让我们先简化一下。你知道吗

逻辑

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)() 

这意味着动态设置默认值只是无用的杂音,因为没有默认参数就永远不会调用Multiplierright?你知道吗

我们可以把它简化为:

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)

对吗?你知道吗

对于那些急于“这不是一个真正的问题”的人来说。。。再读一遍,我的问题用粗体+斜体


Tags: 代码selfnonereturnobjectinitisdef
1条回答
网友
1楼 · 发布于 2024-09-30 22:15:13

问题1。我们可以一直以这种方式访问属性吗?你知道吗

答:没有。只有那些属性以双下划线开头。它们以这种方式被混淆,以防止类外部的意外访问/重写。你知道吗

问题2:我们只是在这里更改__init__中因子参数的默认值吗?你知道吗

A:是的。你知道吗

问题2:是吗?你知道吗

是的。你知道吗

相关问题 更多 >