python __init__与运营商'或'分配

时间:2017-06-07 03:30:32

标签: python python-2.7

import operator

class ClassTupleMeta(type):
    def __init__(cls, *args, **kwargs):
        super(ClassTupleMeta, cls).__init__(*args, **kwargs)
        for n, name in enumerate(cls._fields):
            setattr(cls, name, property(operator.itemgetter(n)))

class ClassTuple(tuple):
    _fields = []
    __metaclass__ = ClassTupleMeta
    def __new__(cls, *args):
        if (len(args) != len(cls._fields)):
            raise ValueError('{} arguments required',format(len(cls._fields)))
        return super(ClassTuple, cls).__new__(cls, args)

class CommonConstExam(ClassTuple):
    _fields = ['long_run_50', 'long_run_800', 'long_run_1000']

    def __init__(self, *arg):
        super(CommonConstExam, self).__init__()
        #setattr(self, 'long_run', self.long_run_50 or self.long_run_800 or self.long_run_1000)

请参阅上面的代码,对于最后一行,总是有一个long_run_50,self.long_run_800,self.long_run_1000,其中包含非None值,我尝试将非None值分配给long_run,但总是会为long_run_50赋值,无论是否为None。而且,如果我将其重写为if-else子句,则会在first if子句中为其赋值。有人知道如何解决这个问题吗?我真的只想使用一个变量(long_run),这可以极大地简化以下代码。

1 个答案:

答案 0 :(得分:0)

你说你的问题就在这一行:

setattr(self, 'long_run', self.long_run_50 or self.long_run_800 or self.long_run_1000)

or的问题 - 这样的表达方式是他们有时会做一些你并不意味着的事情:0"",两者都可能是合法且有趣的价值,两者都是算作False。反过来也是如此。例如,假设long_run_50具有字符串值"None"。这可能很难看到。特别是因为它可能是其他地方的一个错误的结果,并且出乎意料。

尝试使用内联if - 表达式,明确指出您的意思,例如

setattr(self, 'long_run',
        self.long_run_50 if self.long_run_50 is not None 
        else 
        self.long_run_800 if self.long_run_800 is not None
        else 
        self.long_run_1000 if self.long_run_1000 is not None
        else "Nyah-nyah-nyah")

我确实想知道为什么你在使用setattr()的时候,就我所知,它也可以

self.long_run = (  ...etc... )

至少有三个很好的理由说明你可能会这样做,但我不得不问。