1

Instead of doing the following:

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

I want to do the following:

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

Why does this not work?

If I have to use the first approach, is there any good way to make sure I don't unintentionally overwrite variables used elsewhere in the project with the same names (e.g. perhaps "a" is a variable used by another object).

9
  • 2
    Why should it work? a, b, c are parameters to the function that are sent by the caller, not values from the class. And why do you care what names other objects use? Commented Sep 30, 2016 at 15:46
  • 4
    Function/method variables' (including their arguments) scope is limited to the function they are used in. You will not be conflicting with anything else in the project. Commented Sep 30, 2016 at 15:46
  • 1
    Why do you want to do this? It doesn't work because a function in a class is created before the class object, and self is just another argument name. Commented Sep 30, 2016 at 15:46
  • 2
    @PProteus: why do you think shadowing a global is an issue? Only that one function that shadows the name won't be able to access the global object. If that's an issue in that one function, just rename that one argument at a later time. Commented Sep 30, 2016 at 15:54
  • 1
    @PProteus: no, Python has proper scoping. Commented Sep 30, 2016 at 16:39

1 Answer 1

2

Instead of doing the following:

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

I want to do the following:

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

Why does this not work?

This doesn't work because it simply invalid syntax. Python will not allow for you to use self. because your syntax is not valid. Lets take look at the EBNF for function arguments in Python:

parameters: '(' [typedargslist] ')'

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

tfpdef: NAME [':' test]

You may or may not be able to tell from the above snippet of EBNF, but Python does not allow the . operator in parameters. That is why your second method doesn't work.

Lets assume though, that your second example was valid Python syntax. Would it work? The short answer is still no. This is simple because of how Python parses function/method parameters. Lets look at this example:

>>> 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
>>> 

What happened? Why did Python raise a NameError when self is clearly defined.

While Python is in the middle of parsing bar is sees the parameter self. But while Python has "seen" the self parameter, it had not defined it as a name. So when Python tries to parse the second parameter, it becomes confused, and raises a NameError. This behavior is not just exclusive to methods however. Functions have the same problems as well:

>>> 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

To sum it up; The real reason that your second examples doesn't work is because it's invalid Python syntax. But even if it did somehow work, Python would still raise an error due to the way it parses parameters.

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry, why doesn't it make sense that parameters of a function are class attributes? What if it is a "set" function, the purpose of which is to set the three variables a, b, and c?
@PProteus gimme some time to make a more elaborate answer to address your question. It shouldn't take to long though.
leaf, I'm eagerly awaiting your explanation!
@PProteus Alright. Now, see how that answer is :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.