在函数参数定义中使用“self”

时间:2016-09-30 15:44:33

标签: python

而不是执行以下操作:

def MyFunc(self, a, b, c)
    self.a = a
    self.b = b
    self.c = c

我想做以下事情:

def MyFunc(self, self.a, self.b, self.c)

为什么这不起作用?

如果我必须使用第一种方法,是否有任何好方法可以确保我不会无意中用相同的名称覆盖项目中其他地方使用的变量(例如,“a”可能是另一个对象使用的变量)

1 个答案:

答案 0 :(得分:1)

  

而不是执行以下操作:

def MyFunc(self, a, b, c)
    self.a = a
    self.b = b
    self.c = c
     

我想做以下事情:

def MyFunc(self, self.a, self.b, self.c)
     

为什么这不起作用?

这不起作用,因为它只是无效的语法。 Python不允许您使用self.,因为您的语法无效。让我们看一下Python中函数参数的EBNF

parameters: '(' [typedargslist] ')'

typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [','
  ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' >tfpdef]]
|  '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' >tfpdef)

tfpdef: NAME [':' test]

您可能会或可能无法从上面的EBNF片段中判断,但Python不允许.运算符参数。这就是为什么你的第二种方法不起作用的原因。

让我们假设,您的第二个示例是有效的Python语法。会有用吗?简短的回答仍然是没有。这很简单,因为Python解析函数/方法参数。让我们看一下这个例子:

>>> class Foo:
    def __init__(self):
        pass
    def bar(self, x=self):
        pass


Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    class Foo:
  File "<pyshell#13>", line 4, in Foo
    def bar(self, x=self):
NameError: name 'self' is not defined
>>> 

发生什么事了?为什么在明确定义NameError时Python会引发self

虽然Python正在解析bar,但是会看到参数self。但是,虽然Python已经&#34;见过&#34; self参数,它没有将其定义为名称。因此,当Python尝试解析第二个参数时,它会变得混乱,并引发NameError。这种行为不仅仅是排他性的 然而,方法。功能也有同样的问题:

>>> def foo(a, b=a+1):
    return a, b

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    def foo(a, b=a+1):
NameError: name 'a' is not defined

总结一下;您的第二个示例不起作用的真实原因是因为它的Python语法无效。但即使它以某种方式工作,Python仍然会因为它解析参数的方式而引发错误。