Why is my python function not defined, when it exists in the same file?
Asked Answered
B

2

5

I have a simple function, which I shall call myFunction. It takes two parameters, performs some calculations on them, and returns the result.

I also have a class, MyClass, which has a constructor that has a header like this:

__init__(self, bar, fun=myFunction):

When I try to run anything in this class, I get the following error:

MyClass
    def __init__(self, bar, fun=myFunction):
NameError: name 'myFunction' is not defined

If I remove this class, I can use myFun in the Python Shell, so what's the deal?

Baggy answered 22/6, 2012 at 23:30 Comment(1)
Please mark proper answer as a solution. We choose solutions that way, not by telling what is the solution by editing the question.Rodgerrodgers
E
13

You haven't shown the actual code so it's hard to be sure, but I bet myFunction is defined after MyClass. The default value expression is evaluated when the __init__ method is defined, so myFunction must be defined at that point. Defining it later is too late.

Eva answered 22/6, 2012 at 23:45 Comment(12)
Wow, you're right. All I did was cut and paste myFunction so that it is above MyClass in that file, and now everything is fine. Python is weird. Thanks.Baggy
+1 Exactly. To achieve similar effect, you can assign None (or anything else, but it must be defined) as default argument and later compare and eventually assign the myFunction function (this assignment will be evaluated when the method is actually called).Rodgerrodgers
@user1123936: Python is one of the simplest (not meaning it is not powerful), easiest, most consistent programming languages I have ever known. Probably he is first in all of the above, so if you could mention something better, I would be very grateful :) Really.Rodgerrodgers
@Baggy the problem is that Python tries to read the file down and parses everything without executing until it can't anymore (because it needs to do some sort of calculation to parse the rest). I don't know the exact rationale behind it, but it makes intuitive sense as a tradeoff: you want to be able to dynamically execute and change your code on the fly without compiling, but you also want to be able to optimize it where possible.Tonguelash
@JeffTratner Python does execute as it reads. def is a statement. The def my_function(): ... block is executed when Python encounters it. The result of this execution is to create an object representing the code of the function, and assign it the name my_function.Subheading
@JeffTratner: you are a bit confused about the semantics of Python files. A Python file is a series of statements. Each statement is executed in turn from the top of the file to the end. Period. def and class are both statements. They are just assignment statements with special syntax to define functions and classes.Eva
@NedBatchelder Thanks for the clarification. I thought there was something about how Python keeps reading down until it hits some "difficult" calculation, which is why some python scripts can reference things before they are defined. Is that never true? I feel like I've seen code that does this.Tonguelash
You can never use a name before it's defined. Note that you can define a function that uses a name before the name is defined, because the name isn't used until the function is invoked.Eva
@NedBatchelder so basically, you can use not-yet-defined names within a function scope/block, but outside of that, every identifier/name must be defined before being used?Tonguelash
Now I'm having a similar problem, I think. I declared a static variable: bar = 0 at the top of my file. When I try to access it in a function it says it's not defined yet. UnboundLocalError: local variable 'bar' reverenced before assignment Any ideas?Baggy
@user1123936: I'll take another guess: you are trying to assign to bar inside the function, which makes it local throughout the function, so your first check of the value is accessing an UnboundLocal. Read up on the global statement.Eva
Thanks, that fixed everything.Baggy
E
-6

myFunction is a variable, not a value so you can't use it as a default parameter.

Maybe you could use a lambda function as the default parameter instead of the name of a declared function.

Existentialism answered 22/6, 2012 at 23:33 Comment(2)
I did this exact same thing in another project though. MyClass and myFunction are actually both copied and pasted from there.Baggy
-1: Of course you are wrong (here: "_...is a variable, not a value so you can't use it as a default parameter..."). You can use anything you like as a default argument, but it (the assignment of this to the default argument) will be evaluated when the function (the one that has mentioned default argument) will be defined.Rodgerrodgers

© 2022 - 2024 — McMap. All rights reserved.