osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How should we use global variables correctly?


On 23Aug2019 14:43, Windson Yang <wiwindson at gmail.com> wrote:
>I also want to know what is the difference between "using 'global
>variables' in a py module" and "using a variable in class". For example:
>
>In global.py:
>
>    foo = 1
>    def bar():
>        global foo
>        return foo + 1
>
>In class.py
>
>     class Example:
>        def __init__(self):
>            self.foo = 1
>        def bar()
>            return self.foo + 1

This isn't a class variable. The .foo attribute will be attached to 
"self", which is an instance of the class, not the class itself.

You probably want:

    class Example2:
        foo = 1
        def __init__(self):
            pass

So what's happening here? When the class is defined, in addition to 
defining the .__init__ method we also define .foo. These are attributes 
of the class: there's just one of each.

In your code you're setting .foo on "self", so there's one per instance 
of the class.

So in my Example2 there's a foo:

  print(Example2.foo)

works.

Compared to a global, this is nicely contained in the class' namespace.  
But otherwise it is the same: it gets defined just once as the module is 
imported (which defines the class Example2, which defines Example2.foo).

However, it _is_ harder to use as a local by accident. Here:

    from example_module import Example2

    z = 1

    def f():
      z = 3
      Example2.foo = 3

Here, "z" is local to "f" because it is assigned to. Example2.foo is 
still the one from inside the class - we're not assigning to a function 
local name, but to a name _accessed_ via Example2.

>Expect the syntax, why using class variable self.foo would be better 
>(or more common)? I think the 'global' here is relative, foo is global in
>global.py and self.foo is global in Example class.

As mentioned, in your Example class self.foo is an attribute of the 
instance, not the class. My Example2 class shows how to put it on the 
class.

>If the global.py is
>short and clean enough (didn't have a lot of other class), they are pretty
>much the same. Or I missed something?

Making a class level name has the nice aspect that it has a better 
conceptual context.

Cheers,
Cameron Simpson <cs at cskk.id.au>