3
class Pen(object):
    def __init__(self, mean_radius = None, length = None):
        self.usage = "Is used to apply ink trails to drawing surfaces"
        self.mean_radius = mean_radius
        self.length = length

class FountainPen(Pen):
    def __init__(self, manufacturer = "Waterman", *args, **kwargs):
        Pen.__init__(self, *args, **kwargs)
        self.manufacturer = manufacturer
        self.cartridge_state =  "non-empty"

>>> instance_FP = FountainPen(5, 1)
>>> instance_FP.mean_radius
>>> print instance_FP.mean_radius
1    
>>> print instance_FP.length
None

5在 的实例化中作为参数传递的整数会发生什么FountainPen?为什么print instance_FP.mean_radius返回1而不返回5

4

4 回答 4

6

您必须这样想:*args**kwargs“吃掉”它们之前的“常规”参数留下的所有位置/关键字参数。如果你把它们放在最后,它们只会得到不符合“常规论点”的东西。

因此,当您编写FountainPen(5,1)时会发生这样FountainPen.__init__的调用:

  • self设置为新创建的实例;
  • manufacturer获取第一个参数,即 5;
  • *args“吃掉”所有剩余的位置参数,即 just 1; 所以args现在设置为[1];
  • *kwargs会吃掉剩下的任何关键字参数,但没有,所以它变成{}.

很明显,它Pen.__init__只是1作为参数调用(除了self),并length保持设置为其默认值(None)。

于 2012-06-24T12:02:02.683 回答
2

Matteo Italia提到了什么是错误的,基本上manufacturer是一个立场论点。FountainPen您可以通过将'稍微更改__init__为以下内容来修复它:

def __init__(self, *args, manufacturer = "Waterman", **kwargs):

这样做会产生manufacturer一个关键字参数,因此要更改它,您必须调用:

FountainPen(manufacturer="newval")

注意:不幸的是,这种语法(在参数之后只有关键字*args参数)只在 Python 3 中有效。Jon Clements 有一个解决方案可以解决 Python 2 的这个问题。

于 2012-06-24T12:06:16.877 回答
2

一个更优雅的解决方案是:

class FountainPen(Pen):
    def __init__(self, *args, **kwargs):
        Pen.__init__(self, *args, **kwargs)
        self.manufacturer = kwargs.get('manufacturer', 'Waterman')
        self.cartridge_state =  "non-empty"

blah = FountainPen(5, 1, manufacturer='Waterman')
于 2012-06-24T12:07:47.093 回答
0

在您的代码中,将 5 分配给参数manufacturer,将 1 分配给*args.

将不带键的参数传递给函数时,您必须首先提供显式参数。其余的被传递给 *args。为避免这种情况,请在调用构造函数时提供关键字:

>>> instance_FP = FountainPen(mean_radius=5, length=1)
于 2012-06-24T12:01:42.367 回答