Edit 5: As @user3022222 pointed out below, I botched this example in my original posting. I believe this fails because only functions (not other code blocks, like this class definition) can access variables in the enclosing scope. For non-function code blocks, only local, global and built-in variables are accessible. A more thorough explanation is available in this questionOne more:Example 4.>>> def my_defining_func():... def mymethod(self):... return self.y... class MyClass(object):... mymethod = mymethod... y = 3... return MyClass...>>> my_defining_func()Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in my_defining_func File "<stdin>", line 5, in MyClassNameError: name 'mymethod' is not definedUm...excuse me?What makes this any different from example 2?I'm completely befuddled. Please sort me out.Thanks!P.S. on the off-chance that this isn't just a problem with my understanding, I've tried this on Python 2.5.2 and Python 2.6.2. Unfortunately those are all I have access to at the moment, but they both exhibit the same behaviour.EditAccording to http://docs.python.org/tutorial/classes.html#python-scopes-and-namespaces: at any time during execution, there are at least three nested scopes whose namespaces are directly accessible:the innermost scope, which issearched first, contains the localnamesthe scopes of any enclosingfunctions, which are searchedstarting with the nearest enclosingscope, contains non-local, but alsonon-global namesthe next-to-last scope contains thecurrent module’s global namesthe outermost scope (searched last)is the namespace containing built-innames#4. seems to be a counter-example to the second of these.Edit 2Example 5.>>> def fun1():... x = 3... def fun2():... print x... return fun2...>>> fun1()()3Edit 3As @Frédéric pointed out the assignment of to a variable of the same name as it has in the outer scope seems to "mask" the outer variable, preventing the assignment from functioning.So this modified version of Example 4 works:def my_defining_func(): def mymethod_outer(self): return self.y class MyClass(object): mymethod = mymethod_outer y = 3 return MyClassmy_defining_func()However this doesn't:def my_defining_func(): def mymethod(self): return self.y class MyClass(object): mymethod_temp = mymethod mymethod = mymethod_temp y = 3 return MyClassmy_defining_func()I still don't fully understand why this masking occurs: shouldn't the name binding occur when the assignment happens?This example at least provides some hint (and a more useful error message):>>> def my_defining_func():... x = 3... def my_inner_func():... x = x... return x... return my_inner_func...>>> my_defining_func()()Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in my_inner_funcUnboundLocalError: local variable 'x' referenced before assignment>>> my_defining_func()<function my_inner_func at 0xb755e6f4>So it appears that the local variable is defined at function creation (which succeeds), resulting in the local name being "reserved" and thus masking the outer-scope name when the function is called.Interesting.Thanks Frédéric for the answer(s)!For reference, from the python docs:Edit 4The Real AnswerThis seemingly confusing behaviour is caused by Python's statically nested scopes as defined in PEP 227. It actually has nothing to do with PEP 3104.From PEP 227:Lets run two simpler versions of Tim's example:>>> i = 6>>> def f(x):... def g():... print i... # ...... # later... # ...... i = x... g()...>>> f(3)3when g() doesn't find i in its inner scope, it dynamically searches outwards, finding the i in f's scope, which has been bound to 3 through the i = x assignment.But changing the order the final two statements in f causes an error:>>> i = 6>>> def f(x):... def g():... print i... # ...... # later... # ...... g()... i = x # Note: I've swapped places...>>> f(3)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 7, in f File "<stdin>", line 3, in gNameError: free variable 'i' referenced before assignment in enclosing scopeRemembering that PEP 227 said "The name resolution rules are typical for statically scoped languages", lets look at the (semi-)equivalent C version offer:// nested.c#include <stdio.h>int i = 6;void f(int x){ int i; // <--- implicit in the python code above void g(){ printf("%d\n",i); } g(); i = x; g();}int main(void){ f(3);}compile and run:$ gcc nested.c -o nested$ ./nested1345208203So while C will happily use an unbound variable (using whatever happens to have been stored there before: 134520820, in this case), Python (thankfully) refuses.As an interesting side-note, statically nested scopes enable what Alex Martelli has called "the single most important optimization the Python compiler does: a function's local variables are not kept in a dict, they're in a tight vector of values, and each local variable access uses the index in that vector, not a name lookup." 解决方案 That's an artifact of Python's name resolution rules: you only have access to the global and the local scopes, but not to the scopes in-between, e.g. not to your immediate outer scope.EDIT: The above was poorly worded, you do have access to the variables defined in outer scopes, but by doing x = x or mymethod = mymethod from a non-global namespace, you're actually masking the outer variable with the one you're defining locally.In example 2, your immediate outer scope is the global scope, so MyClass can see mymethod, but in example 4 your immediate outer scope is my_defining_func(), so it can't, because the outer definition of mymethod is already masked by its local definition.See PEP 3104 for more details about nonlocal name resolution.Also note that, for the reasons explained above, I can't get example 3 to run under either Python 2.6.5 or 3.1.2:>>> def myfunc():... x = 3... class MyClass(object):... x = x... return MyClass...>>> myfunc().xTraceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in myfunc File "<stdin>", line 4, in MyClassNameError: name 'x' is not definedBut the following would work:>>> def myfunc():... x = 3... class MyClass(object):... y = x... return MyClass...>>> myfunc().y3 这篇关于在函数内创建类并访问包含函数范围内定义的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-20 10:58