Python 最";蟒蛇的;组织类属性、构造函数参数和子类构造函数默认值的方式?
由于对Python2比较陌生,我不确定如何以最“pythonic”的方式组织我的类文件。我不会问这个问题,但事实上Python似乎有很多不同于我从我习惯的语言中所期望的方式 起初,我只是用C#或PHP处理类,当我最终发现可变值时,这当然让我大吃一惊,明白了:Python 最";蟒蛇的;组织类属性、构造函数参数和子类构造函数默认值的方式?,python,python-2.6,Python,Python 2.6,由于对Python2比较陌生,我不确定如何以最“pythonic”的方式组织我的类文件。我不会问这个问题,但事实上Python似乎有很多不同于我从我习惯的语言中所期望的方式 起初,我只是用C#或PHP处理类,当我最终发现可变值时,这当然让我大吃一惊,明白了: class Pants(object): pockets = 2 pocketcontents = [] class CargoPants(Pants): pockets = 200 p1 = Pants() p
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
哎呀!没想到
我花了很多时间在网络上搜索,并通过一些其他项目的源代码寻找如何最好地安排我的类的提示,我注意到的一件事是,人们似乎在构造函数中声明了许多实例变量——可变或其他——而且默认构造函数参数堆得很厚
在像这样发展了一段时间之后,我仍然对它的不熟悉有些挠头。考虑到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"
撇开轻微的愚蠢不谈(我在编写这些人工示例类时真的忍不住),假设我在现实世界中需要一组具有这么多属性的类,我想我的问题是:
- 声明一个具有这么多属性的类的最“pythonic”的方式是什么?如果默认值是不可变的,那么最好将它们放在类中,还是最好将它们放在构造函数中,即ala ClassWithLotsOfAttributes.Noisence
- 是否有一种方法可以消除重新声明所有子类构造函数参数的默认值的需要,如Dog.\uuu init\uuuu?我是否应该包含这么多带有默认值的参数
- 如果属性因实例而异
以身作则
属性,即创建它们
在
内部使用self进行初始化 可以在类实例之间共享 像常数一样,把它们放在课堂上 水平
- 如果你的课程真的需要通过,那么
中的许多参数 派生类使用参数列表和 关键字参数,例如\uuuu init\uuuu
CoolDog(True)
CoolDog(True, old=False)
CoolDog(bite=True, old=True)
CoolDog(old=True, bite=False)
+我一定喜欢你的榜样。还有一个好问题。哦,我不知道你可以这样使用*args和**kwargs“酷”这个词肯定要升级为“真的很酷!!!”:)另外,Dog.\uuu init\uuuuu需要添加额外的构造函数参数的情况如何?定义初始值(self,legs=4,*args,**kwargs)是正确的方法吗?是的,您可以特别检查kargs中的var名称,我将添加一个示例“make them instance attribute,即在初始值内创建它们”->真正重要的是使用
self
而不是类。我认为这对初学者来说可能会有误导性。实际上你可以使用它,但我添加了pop,这样你也可以在需要时访问基类参数
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!!!
CoolDog(True)
CoolDog(True, old=False)
CoolDog(bite=True, old=True)
CoolDog(old=True, bite=False)