python - 大多数 "pythonic"组织类属性、构造函数参数和子类构造函数默认值的方式?

标签 python python-2.6

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

最初,我只是按照我通常在 C# 或 PHP 中对待类的方式对待类,这当然让我在最终发现可变值陷阱时到处乱跑:

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

哎呀!没想到!

我花了很多时间在网上搜索并通过其他项目的一些资源来寻找有关如何最好地安排我的类(class)的提示,我注意到的一件事是人们似乎声明了很多他们的实例变量- 可变或其他 - 在构造函数中,并且还非常厚地堆放默认构造函数参数。

这样开发了一段时间后,我仍然对它的陌生感有些摸不着头脑。考虑到 python 语言使事情看起来更直观和明显的长度,在我有很多属性或很多默认构造函数参数的少数情况下,这对我来说似乎很奇怪,尤其是当我'm 子类化:

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"

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

  • 声明具有那么多属性的类的最,呃,'pythonic' 方法是什么?如果默认值是不可变的,比如 Pants.pockets,最好将它们放在类中,还是最好将它们放在构造函数中,比如 ClassWithLotsOfAttributes.noisiness?

  • 有没有办法消除重新声明所有子类构造函数参数的默认值的需要,就像在 Dog.__init__ 中一样?无论如何,我是否应该包括这么多带有默认值的参数?

最佳答案

  • 如果属性因实例而异 实例化它们实例 属性即创建它们 在 __init__ 中使用 self else 如果他们需要 在类实例之间共享 像常数一样,把它们放在类里面 水平。

  • 如果你的类(class)真的需要通过,那么 __init__ 中有很多参数,让 派生类使用参数列表和 关键字参数例如

class Dog(ClassWithLotsOfAttributes):
    def __init__(self, *args , **kwargs):
        super(ClassWithLotsOfAttributes,    self).__init__(*args , **kwargs)
        self.coolness = "really cool!!!
  • No need of passing all variables except few important ones, in __init__, class can assume some defaults and user can change them later on if needed.
  • Use 4 spaces instead of tab.

  • if you need to add an extra arg bite, to Dog and keyword arg old too

class CoolDog(ClassWithLotsOfAttributes):
    def __init__(self, bite, *args , **kwargs):
        self.old = kwargs.pop('old', False) # this way we can access base class args too
        super(ClassWithLotsOfAttributes,    self).__init__(*args , **kwargs)
        self.bite = bite
        self.coolness = "really really cool!!!

various ways you useCoolDog

CoolDog(True)
CoolDog(True, old=False)
CoolDog(bite=True, old=True)
CoolDog(old=True, bite=False)

关于python - 大多数 "pythonic"组织类属性、构造函数参数和子类构造函数默认值的方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1118006/

相关文章:

python - Merge_Sort 算法的计数工作

python - 在列值和索引值上对 Pandas 数据框进行排序?

python - 选择要下载文件的哪一部分

Python:破解 gc 之谜

python - 在python中使用zip函数时出错

python - 将 Python 2.5 升级到 Python 2.6 后解决 pip/virtualenv fiasco?

python - 识别列表中字符串中出现的元素

python - Django 3 - 为主键提供默认值时的 Model.save()

python - 在 Python 2.6+ 中使用 super(...) 时如何避免样板代码?

python - 导入模块中全局变量的可见性