Usefulness of def __init__(self)?

后端 未结 3 431
夕颜
夕颜 2021-02-02 06:51

I am fairly new to python, and noticed these posts: Python __init__ and self what do they do? and Python Classes without using def __init__(self)

After playing around w

相关标签:
3条回答
  • 2021-02-02 07:41

    Yeah, check this out:

    class A(object):
        def __init__(self):
            self.lst = []
    
    class B(object):
        lst = []
    

    and now try:

    >>> x = B()
    >>> y = B()
    >>> x.lst.append(1)
    >>> y.lst.append(2)
    >>> x.lst
    [1, 2]
    >>> x.lst is y.lst
    True
    

    and this:

    >>> x = A()
    >>> y = A()
    >>> x.lst.append(1)
    >>> y.lst.append(2)
    >>> x.lst
    [1]
    >>> x.lst is y.lst
    False
    

    Does this mean that x in class B is established before instantiation?

    Yes, it's a class attribute (it is shared between instances). While in class A it's an instance attribute. It just happens that strings are immutable, thus there is no real difference in your scenario (except that class B uses less memory, because it defines only one string for all instances). But there is a huge one in my example.

    0 讨论(0)
  • 2021-02-02 07:45

    As others have stated, it's the difference between a variable on a class and a variable on a class instance. See the following example.

    >>> class A:
    ...     a = []
    ... 
    >>> class B:
    ...     def __init__(self):
    ...         self.b = []
    ... 
    >>> a1 = A()
    >>> a1.a.append('hello')
    >>> a2 = A()
    >>> a2.a
    ['hello']
    >>> b1 = B()
    >>> b1.b.append('goodbye')
    >>> b2 = B()
    >>> b2.b
    []
    

    For immutable objects like tuples, strings, etc. it's harder to notice the difference, but for mutables, it changes everything—the changes applied are shared between ALL instances of that class.

    Note also that the same behavior happens for keyword argument defaults!

    >>> class A:
    ...     def __init__(self, a=[]):
    ...         a.append('hello')
    ...         print(a)
    ... 
    >>> A()
    ['hello']
    >>> A()
    ['hello', 'hello']
    >>> A()
    ['hello', 'hello', 'hello']
    
    >>> class B:
    ...     def __init__(self, b=None):
    ...         if b is None:
    ...             b = []
    ...         b.append('goodbye')
    ...         print(b)
    ... 
    >>> B()
    ['goodbye']
    >>> B()
    ['goodbye']
    >>> B()
    ['goodbye']
    

    This behavior bites a lot of new Python programmers. Good for you in discovering these distinctions early on!

    0 讨论(0)
  • 2021-02-02 07:52

    In the first exemple you have the variable of the instance of the class. This variable is only accessible through an instance (self required).

    class A():
        def __init__(self):
            self.x = 'hello'
    
    print A.x -> AttributeError
    print A().x -> 'hello'
    

    In the second exemple you have a static variable. You can access to this variable thanks to the name of the class A

    class A():
      x = 'hello'
    
    print A.x -> 'hello'
    print A().x -> 'hello'
    

    In fact you can have a static variable and an instance variable with the same name:

    class A():
        x = 'hello'
        def __init__(self):
            self.x = 'world'
    
    print A.x -> hello
    print A().x -> world
    

    The static value is shared between all the instances

    class A():
        x = 'hello'
    
        @staticmethod
        def talk():
            print A.x
    
    a = A()
    print a.talk() -> hello
    
    A.x = 'world'
    print a.talk() -> world
    

    You have a good article here: http://linuxwell.com/2011/07/21/static-variables-and-methods-in-python/

    0 讨论(0)
提交回复
热议问题