简体   繁体   中英

Understanding behaviour of self with static variables

I am confused with the behaviour of self when it comes to dealing with static variables in python.From what I understand is that static variables can be accessed by either using classname.variablename or self.variablename . However changing the value of that variable differs. I realized that if i change the static variable value by classname.variablename=SomeValue the instance variable reflects that value however if I change the value of static variable using self.variablename=SomeValue the static variable does not change when access like classname.variablename from what I understand is that when I assign a value like self.variablename=SomeValue then an instance variable is created. Can somebody please shed a little light on this behaviour.

Example 1:

class bean:
    mycar="SomeCar"
    def test(self):
        bean.mycar = "yup"
        print(self.mycar) #prints yup

Example 2:

class bean:
        mycar="SomeCar"
        def test(self):
            self.mycar = "pup"
            print(bean.mycar) #SomeCar

self in python is an ordinary name that binds the reference to the instance calling a class method. It is passed as the first argument to a method and by convention, it is bound to the name 'self'. When self.variable = value is called, you are setting the value of an instance variable; a variable unique to that particular bean .

For example, self.name = "Fred" might name my mother's bean, but I named my own bean "George" when I called self.name from my bean.

On the other hand, bean.name = "Yousef" names all beans. My mother's bean is now named "Yousef", and so is mine.

If my Dad has a bean as well, he'll be surprised to find out that it too, is named "Yousef" when he calls bean.name . But he can still use self.name to give his bean its own (possibly unique) name.

Example Code:

class bean:
    name = "Yousef"  # All beans have this name with `bean.name`

moms = bean()
mine = bean()
dads = bean()

beans = [moms, mine, dads]

# Primitive tabular output function
def output(bean_list):
    print("-bean-", "\t", "-self-")
    for b in bean_list:
        print(bean.name, "\t", b.name)
    print("") # Separate output sets with a newline

# Print the names with only the class attribute set
output(beans)

# Python magic using zip to apply names simultaneously
# Mom's bean is "Fred", mine is "George"
# My dad is weird and named his "Ziggaloo"
for b, n in zip(beans, ["Fred", "George", "Ziggaloo"]):
    b.name = n

# Print the names after applying `self.name`
output(beans)

Python 3.4 Output:

-bean-   -self-
Yousef   Yousef
Yousef   Yousef
Yousef   Yousef

-bean-   -self-
Yousef   Fred
Yousef   George
Yousef   Ziggaloo

Both classes and instances can have attributes.

A class attribute is assigned to a class object. People sometimes call this a "static variable" .

An instance attribute is assigned to an instance ( "instance variable" ).

When an attribute of an object is read , a number of things happen (see Descriptor HowTo Guide ), but the short version is:

  1. Try to read the attribute from the instance
  2. If that fails, try to read it from the class

When it is written , then there is no such mechanism. It is written where it is written ;)

See in example:

class A(object):
    pass

a = A()

print A.value  # fails - there is no "value" attribute
print a.value  # fails - there is no "value" attribute

A.value = 7

print A.value  # prints 7
print a.value  # also prints 7 - there is no attribute on instance, but there is on class

a.value = 11

print A.value  # prints 7
print a.value  # prints 11 - now there is an attribute on the instance

a2 = A()

print a2.value  # prints 7 - this instance has no "value", but the class has

self?

BTW, the self argument (in the question) is an instance, just like a is here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM