difference between variables inside and outside of __init__()

前端 未结 10 694
醉酒成梦
醉酒成梦 2020-11-22 17:08

Is there any difference at all between these classes besides the name?

class WithClass ():
    def __init__(self):
        self.value = \"Bob\"
    def my_fu         


        
相关标签:
10条回答
  • 2020-11-22 17:29

    classes are like blueprints to create objects. Let's make a metaphor with building a house. You have the blueprint of the house so you can build a house. You can build as many houses as your resources allow.

    In this metaphor, the blueprint is the class and the house is the instantiation of the class, creating an object.

    The houses have common attributes like having a roof, living room, etc. This is where you init method goes. It constructs the object (house) with the attributes you want.

    Lets suppose you have:

    `class house:`
    `roof = True`
    `def __init__(self, color):`
    `self.wallcolor = color`
    

    >> create little goldlock's house:

    >> goldlock = house() #() invoke's class house, not function
    
    >> goldlock.roof
    
    >> True
    
    all house's have roofs, now let's define goldlock's wall color to white:
    
    >> goldlock.wallcolor = 'white'
    >>goldlock.wallcolor
    >> 'white'
    
    0 讨论(0)
  • 2020-11-22 17:38

    Without Self

    Create some objects:

    class foo(object):
        x = 'original class'
    
    c1, c2 = foo(), foo()
    

    I can change the c1 instance, and it will not affect the c2 instance:

    c1.x = 'changed instance'
    c2.x
    >>> 'original class'
    

    But if I change the foo class, all instances of that class will be changed as well:

    foo.x = 'changed class'
    c2.x
    >>> 'changed class'
    

    Please note how Python scoping works here:

    c1.x
    >>> 'changed instance'
    

    With Self

    Changing the class does not affect the instances:

    class foo(object):
        def __init__(self):
            self.x = 'original self'
    
    c1 = foo()
    foo.x = 'changed class'
    c1.x
    >>> 'original self'
    
    0 讨论(0)
  • 2020-11-22 17:40
    class User(object):
        email = 'none'
        firstname = 'none'
        lastname = 'none'
    
        def __init__(self, email=None, firstname=None, lastname=None):
            self.email = email
            self.firstname = firstname
            self.lastname = lastname
    
        @classmethod
        def print_var(cls, obj):
            print ("obj.email obj.firstname obj.lastname")
            print(obj.email, obj.firstname, obj.lastname)
            print("cls.email cls.firstname cls.lastname")
            print(cls.email, cls.firstname, cls.lastname)
    
    u1 = User(email='abc@xyz', firstname='first', lastname='last')
    User.print_var(u1)
    

    In the above code, the User class has 3 global variables, each with value 'none'. u1 is the object created by instantiating this class. The method print_var prints the value of class variables of class User and object variables of object u1. In the output shown below, each of the class variables User.email, User.firstname and User.lastname has value 'none', while the object variables u1.email, u1.firstname and u1.lastname have values 'abc@xyz', 'first' and 'last'.

    obj.email obj.firstname obj.lastname
    ('abc@xyz', 'first', 'last')
    cls.email cls.firstname cls.lastname
    ('none', 'none', 'none')
    
    0 讨论(0)
  • 2020-11-22 17:41

    Variable set outside __init__ belong to the class. They're shared by all instances.

    Variables created inside __init__ (and all other method functions) and prefaced with self. belong to the object instance.

    0 讨论(0)
  • 2020-11-22 17:41
    class foo(object):
        mStatic = 12
    
        def __init__(self):
            self.x = "OBj"
    

    Considering that foo has no access to x at all (FACT)

    the conflict now is in accessing mStatic by an instance or directly by the class .

    think of it in the terms of Python's memory management :

    12 value is on the memory and the name mStatic (which accessible from the class)

    points to it .

    c1, c2 = foo(), foo() 
    

    this line makes two instances , which includes the name mStatic that points to the value 12 (till now) .

    foo.mStatic = 99 
    

    this makes mStatic name pointing to a new place in the memory which has the value 99 inside it .

    and because the (babies) c1 , c2 are still following (daddy) foo , they has the same name (c1.mStatic & c2.mStatic ) pointing to the same new value .

    but once each baby decides to walk alone , things differs :

    c1.mStatic ="c1 Control"
    c2.mStatic ="c2 Control"
    

    from now and later , each one in that family (c1,c2,foo) has its mStatica pointing to different value .

    [Please, try use id() function for all of(c1,c2,foo) in different sates that we talked about , i think it will make things better ]

    and this is how our real life goes . sons inherit some beliefs from their father and these beliefs still identical to father's ones until sons decide to change it .

    HOPE IT WILL HELP

    0 讨论(0)
  • 2020-11-22 17:42

    In Python, a class comes with member functions (methods), class variables, attributes/instance variables (and probably class methods too):

    class Employee:
    
        # Class Variable
        company = "mycompany.com"
    
        def __init__(self, first_name, last_name, position):
            # Instance Variables
            self._first_name = first_name
            self._last_name = last_name
            self._position = position
    
        # Member function
        def get_full_name(self):
            return f"{self._first_name} {self._last_name}"
    

    By creating an instance of the object

    my_employee = Employee("John", "Wood", "Software Engineer")
    

    we essentially trigger __init__ that is going to initialise the instance variables of the newly created Employee. This means that _first_name, _last_name and _position are explicit parameters of the specific my_employee instance.

    Likewise, member functions return information or change the state of a specific instance.


    Now any variable defined outside the constructor __init__ are considered to be class variables. Those variables are shared amongst all the instances of the class.

    john = Employee("John", "Wood", "Software Engineer")
    bob = Employee("Bob", "Smith", "DevOps Engineer0")
    
    print(john.get_full_name())
    print(bob.get_full_name())
    print(john.company)
    print(bob.company)
    
    >>> John Wood
    >>> Bob Smith
    >>> mycompany.com
    >>> mycompany.com
    

    You can also use class methods in order to change the class variable for all the instances of the class. For example:

    @classmethod
    def change_my_companys_name(cls, name):
        cls.company = name
    

    and now change_my_companys_name()

    bob.change_my_companys_name("mynewcompany.com")
    

    will have effect on all the instances of class Employee:

    print(bob.company)
    print(john.company)
    
    >>> mynewcompany.com
    >>> mynewcompany.com
    
    0 讨论(0)
提交回复
热议问题