1
class A:
    name = 10  # this is a class variable

    def fun(self):
        print('this is a function')
        return name  # this is the return value, but same 'name'

name = A()
name.fun()
print(name.fun())
# operation result
this is a function
this is a function
<__main__.A object at 0x000001D95A894508>

It can run successfully, but it does not conform to grammatical logic, why does it(the 'name') not report an error?

Gabio
  • 9,126
  • 3
  • 12
  • 32
holaforce
  • 11
  • 2
  • 3
    Just FYI, Python uses an *interpreter*, not a *compiler*. – 0x5453 Apr 28 '20 at 13:05
  • Are you wondering why you can use the variable name both globally and within the class and the interpreter can differentiate the two instances? If so, [this may be useful](https://www.python-course.eu/python3_global_vs_local_variables.php) – DarrylG Apr 28 '20 at 13:08
  • You have two variables called "name", one in the class namespace, one in the scripts global namespace. So no clash. If you did try to use `name` twice in the same namespace, python would happily overwrite one with the other. Its a dynamic language. – tdelaney Apr 28 '20 at 13:10
  • 5
    It's the global name you used here `name = A()`. Change that to say `foo = A()` and it will complain about `return name`. – Spencer Wieczorek Apr 28 '20 at 13:11
  • @SpencerWieczorek - I didn't notice that! `return name` is a bug. It only happens to "work" because there is a `name` in the global namespece. – tdelaney Apr 28 '20 at 13:15

2 Answers2

0

Your fun function is valid due to the fact that it references the variable name from the global scope (if you name the object of class A you've initialized with another name, your code will break).

For example - this code won't work:

class A:
    name = 10  # this is a class variable

    def fun(self):
        print('this is a function')
        return name  # this is the return value, but same 'name'

object_a = A()
object_a.fun()

In your global scope, name is defined as an object of class A so running name.fun() will execute the function fun of this object.

If you want to access the local variable name defined in the class, you can try to run this:

name = A()
print(name.name) # output: 10
Gabio
  • 9,126
  • 3
  • 12
  • 32
0

You have a bug that is masked by the fact that you use name in the global namespace. When you use a variable in a method, python checks the method namespace and then falls back to the global namespace. return name doesn't see a local name but by luck (bad luck), there is a name in the global namespace and that is what is returned. If you used that return value later, you'd find it has an instance of A in it.

Instead, use the self.name reference. Python will find self in the method namespace and seeing that it is an object instance namespace will first check the object namespace and then fall back to the class namespace.

class A:
    name = 10  # this is a class variable

    def fun(self):
        print('this is a function')
        return self.name  # this is the return value, but same 'name'

foo = A()
name = foo.fun() 
# three references to the same object
print(name, A.name, foo.name)
tdelaney
  • 73,364
  • 6
  • 83
  • 116