什么是创建类属性的'Python'方式

时间:2011-07-29 07:50:21

标签: python

我是Python的初学者。我想知道哪个是创建属性的更好方法......

在第一个方法中,我明确定义了属性,然后让方法返回一个值:

class A:
    def __init__(self, number):
        self.a = self._meth( number)

    def _meth(self, num):
        #some executable code here

        return 8 ** num

在第二个变体中,该方法由其自身调用,并由它自己创建属性。

class A:
    def __init__(self, number):
        self._meth(num)

    def _meth(self, num)
        #some executable code here
        self.a = 8 ** num

所以我的问题是哪一个是更容易接受的方式?

这是我想用于...的代码...

class Initializer():
    def __init__(self):
        self.ParseArguments()
        self.InitializeLogger()

    # Parse command line arguments and display help text    
    def ParseArguments(self):
        help = textwrap.dedent('''\ Help text here''')
        Arguments = argparse.ArgumentParser('This Script Pulls NAV data from the '
                            'AMFI website', 
                            formatter_class=argparse.RawDescriptionHelpFormatter, 
                            description=help)
        Arguments.add_argument('-f', '--file',
                               help= 'location of the config')
        self.ArgumentDict = vars(Arguments.parse_args())
        self.ArgumentParser = Arguments




    def CreateLogFile(self, level, name,):
        path = self.ArgumentDict['loc']
        if path == None:
            if platform.system() == 'Windows':
                location = os.environ.get("TEMP") + '\\' + name
            elif platform.system == 'Linux':
                location = os.getenv("HOME") + '/' + name
            else:
                print "Unsupported OS"
                raise ValueError
        else:
            location = path
        formatter = logging.Formatter("%(asctime)s - %(name)s - "
                                      "%(levelname)s - %(message)s")
        logfile = logging.FileHandler(location)
        logfile.setLevel(logging.DEBUG)
        logfile.setFormatter(formatter)
        self.logger.addHandler(logfile)


    def InitializeLogger(self):
        self.logger = logging.getLogger('main')
        if self.ArgumentDict['debug'] == True:
            self.logger.setLevel(logging.DEBUG)
        else:
            self.logger.setLevel(logging.INFO)
        self.CreateLogFile(logging.INFO, 'NavUpdaterLog.log')) 

5 个答案:

答案 0 :(得分:3)

请注意,您正在创建对象属性,而不是类属性(这些属性直接在类主体中)。如果仅在初始化时调用meth,我更愿意:

class A(object):
    def __init__():
         # Some executable code here
         self.a = 8

否则,如果您的课程无法偶尔处理meth被调用,您应该通过在___前加上一个私有方法。

顺便说一下,方法结束时return None(大写 N 一个)是不必要的,这是默认的最终指令。

查看更新后的代码,我发现首先不需要使用类。你可能想要一个辅助方法initLogger,但就是这样。尝试:

  • 使用内置功能而非自行重新实现,例如tempfile
  • 大致遵循您的风格PEP8(即不要大写方法和变量名称)

答案 1 :(得分:0)

在第二个定义中,您只能使用该方法设置实例变量a。在您的第一个,您可以再次使用该方法,如果您需要它。另外,我不喜欢在整个地方寻找变量,所以我会选择第一位。

答案 2 :(得分:0)

我认为正确的python方式是以最简单的方式完成,删除所有不必要的代码。

class A():
    def __init__(self):
        self.a = 8

如果您需要定义自定义getter和setter,可以使用python properties。这是python文档的摘录:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

答案 3 :(得分:0)

我认为答案取决于它。如果您的示例中只有一个属性,则meth的整个主体可以进入__init__方法。如果你说5-10个属性要初始化,__init__会很长,我肯定会尝试将初始化代码重构为函数。如果每个属性的初始化独立于另一个,我首先尝试使用函数。

def get_attr_a():
    # some code
    return a
def get_attr_b():
    ...
    return b
...
class A:
    def __init__():
        self.a = get_attr_a()
        self.b = get_attr_b()
        ...

如果属性的初始化彼此依赖,那么在完成之前b不能被初始化,那么这是一个棘手的情况。这可能保证某种工厂模式,其中对象的初始化与类分离:

class A:
    def__init__(self, a, b, c):
        self.a, self.b, self.c = a, b, c

def get_attr_a():
    return a
def get_attr_b(a):
    return b
def create_an_a_class():
    a = get_attr_a()
    b = get_attr_b(a)
    c = get_attr_c(a, b)
    ....
    return A(a, b, c)

答案 4 :(得分:0)

使用init是创建属性的一种可理解的方式(对于其他程序员)。

通常__ init __是你的方式我开始阅读python类并扫描方法。