这周的比赛。郎。蟒蛇,一个"有趣"的代码是 发布 由史蒂芬*D'Aprano作为一个笑话回答一个家庭作业的问题。这里是:

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医生, 发现 func_defaults 是"一组包含缺省参数值对于这些论点,这有违约,或者不如果没有的论点有一个默认值". 我们只是改变的默认值 factor 参数 __init__ 在这里? 产生的代码,然后将:

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 是永远不会被称为没有一个缺省参数, ?

我们可能可以简化到:

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)

正确的吗?

而对于那些匆匆"这不是一个真正的问题"...再读一遍我的问题是在大胆+斜体

有帮助吗?

解决方案

Q1。我们可以随时访问的属性,在这个时尚?

A:没有。这只是那些属性的人开始与双下划线。他们获得模糊,在这种方式,以防止意外的接入/压倒一切从外部类。

问题2:我们只是改变的默认值的因素的论点 __init__ 在这里?

A:是的。

问题2:对吗?

正确的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top