组织类属性、构造函数参数和子类构造函数默认值的大多数“pythonic”方法?

2024-03-29 09:24:56 发布

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

作为Python 2的新手,我不确定如何以最“pythonic”的方式最好地组织我的类文件。我不会问这个问题,但事实上Python似乎有很多不同于我所期望的语言的方法。

最初,我只是用C#或PHP来处理类,当我最终发现可变值gotcha时,这当然让我大吃一惊:

class Pants(object):
    pockets = 2
    pocketcontents = []

class CargoPants(Pants):
    pockets = 200

p1 = Pants()
p1.pocketcontents.append("Magical ten dollar bill")
p2 = CargoPants()

print p2.pocketcontents

哎呀!没想到!

我花了很多时间在搜索web和其他项目的一些源代码中寻找如何最好地安排类的提示,我注意到的一件事是,人们似乎在构造函数中声明了很多实例变量(可变的或其他的),并且把默认的构造函数参数堆得很厚。

像这样发展了一段时间后,我还是有点摸不着头脑。考虑到python语言使事情看起来更加直观和明显的长度,在我有很多属性或很多默认构造函数参数的少数情况下,尤其是在我进行子类化时,这对我来说显得非常奇怪:

class ClassWithLotsOfAttributes(object):
    def __init__(self, jeebus, coolness='lots', python='isgoodfun', 
             pythonic='nebulous', duck='goose', pants=None, 
             magictenbucks=4, datawad=None, dataload=None,
             datacatastrophe=None):

        if pants is None: pants = []
        if datawad is None: datawad = []
        if dataload is None: dataload = []
        if datacatastrophe is None: datacatastrophe = []
        self.coolness = coolness
        self.python = python
        self.pythonic = pythonic
        self.duck = duck
        self.pants = pants
        self.magictenbucks = magictenbucks
        self.datawad = datawad
        self.dataload = dataload
        self.datacatastrophe = datacatastrophe
        self.bigness = None
        self.awesomeitude = None
        self.genius = None
        self.fatness = None
        self.topwise = None
        self.brillant = False
        self.strangenessfactor = 3
        self.noisiness = 12
        self.whatever = None
        self.yougettheidea = True

class Dog(ClassWithLotsOfAttributes):
    def __init__(self, coolness='lots', python='isgoodfun', pythonic='nebulous', duck='goose', pants=None, magictenbucks=4, datawad=None, dataload=None, datacatastrophe=None):
        super(ClassWithLotsOfAttributes, self).__init__(coolness, python, pythonic, duck, pants, magictenbucks, datawad, dataload, datacatastrophe)
        self.noisiness = 1000000

    def quack(self):
        print "woof"

撇开轻微的愚蠢不谈(在编写这些人工示例类时,我真的控制不住自己),假设我在现实世界中需要一组具有这么多属性的类,我想我的问题是:

  • 什么是声明一个具有这么多属性的类的最有效的方法?如果默认值是不可变的ala Pants.pockets,那么最好将它们放在类上,还是放在构造函数ala ClassWithLotsOfAttributes.noisensity中更好?

  • 有没有办法消除像Dog中那样重新声明所有子类构造函数参数的默认值?我是不是应该用默认值包含这么多参数呢?


Tags: selfnoneifispythonicclasspantsduck