Variable scopes in Python classes
Asked Answered
C

4

84

Declaring a variable in a class (outside of a function): all class functions can access it (basically a public variable)

Declaring a variable inside a function inside a class: only that function can access it (it's in that function's scope)

Declaring a variable with self.(variable name) inside a function inside a class: all class functions can access it (how is this different from global (variable name)?)

And since there is no private/protected, everything is public, so everything accessible from inside a class is accessible from outside the class.

Are there any other nuances I should know, or have I pretty much got it?

Cockney answered 17/4, 2011 at 1:37 Comment(1)
But basically, yes, ypu don't have things like "private" variables by default in Python (I say "by default" because one can use some introspection magic to have private/protected like behavior). Now, why would you need private variables? The convention is that methods/attributes that have their name starting with a single "_" are not public and should not be modified from outside the object. The idea of private vars for obfuscation/security is faulty by nature.Auld
H
169

Since the listing in your question is not 100% clear, I've decided to explain it with a simple example. It also includes some things like __something variables you did not mention in your list.

class Test:
    a = None
    b = None

    def __init__(self, a):
        print self.a
        self.a = a
        self._x = 123
        self.__y = 123
        b = 'meow'

At the beginning, a and b are only variables defined for the class itself - accessible via Test.a and Test.b and not specific to any instance.

When creating an instance of that class (which results in __init__ being executed):

  • print self.a doesn't find an instance variable and thus returns the class variable
  • self.a = a: a new instance variable a is created. This shadows the class variable so self.a will now reference the instance variable; to access the class variable you now have to use Test.a
  • The assignment to self._x creates a new instance variable. It's considered "not part of the public API" (aka protected) but technically it has no different behaviour.
  • The assignment to self.__y creates a new instance variable named _Test__y, i.e. its name is mangled so unless you use the mangled name it cannot be accessed from outside the class. This could be used for "private" variables.
  • The assignment to b creates a local variable. It is not available from anywhere but the __init__ function as it's not saved in the instance, class or global scope.
Haag answered 17/4, 2011 at 1:45 Comment(4)
Is there a reason why you are not using Test(object)? So does your answer also apply to the new-type classes?Kight
@DavorJosipovic there is a thing called Python3.Barhorst
if we call class like: ** obj = Test("name") ** then this obj is instance or object. what this obj is exactly.Blondell
Also, the argument a in __init__(self, a) is a local variable within __init__ only.Sidecar
G
25

Declaring a variable at the top level of the class is like declaring a static or class variable. Qualifying it with self is declaring an instance variable. Class variables can be modified by referring to them by class name (e.g. Class.x = 5) and all instances will inherit these changes. Instance variables are private to an instance and can only be modified by that instance.

You can achieve some level of access control using underscores. See private variables in the Python tutorial. By convention, variables starting with one underscore, e.g. _foo are non-public parts of an API, and names starting with two underscores e.g. __foo will have it's name mangled to be _classname__foo.

Gruesome answered 17/4, 2011 at 1:41 Comment(0)
H
1

Although answered, let me add some comments to your questions:

Declaring a variable in a class (outside of a function) : all class functions can access it (basically a public variable)

This is like a static variable and can be called using the class name. These variables are available to all functions, any functions can modify it and print it.

Declaring a variable inside a function inside a class : only that function can access it (it's in that function's scope):

If the variable is declared without self then it is accessible within that function only, like a local variable. However, if it was declared using self like self.var= 'somevalue', then it is accessible via any object but not via the class name.

Declaring a variable with self.(variable name) inside a function inside a class : all class functions can access it (how is this different from global (variable name)?)

See answer in the above part.

And since there is no private / protected, everything is public, so everything accessible from inside a class is accessible from outside the class

Yes, but we can use single underscore to tell the world this variable is private, but technically that actually doesn't make it private.

Havener answered 14/9, 2018 at 16:13 Comment(0)
M
-1

we can use the scope in this for as : case 1: In the Class

class test:
     def __init__(self, a):
          self.__elements = a
     def change_a(self): self.__elements = 5

case 2 : Outside class

t = test(5)

This will access by as object._classname__privatevaribalename

print(t._test__elements)

this will print the change value of a

Mcauley answered 12/9, 2018 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.