difference between variables inside and outside of __init__()

前端 未结 10 695
醉酒成梦
醉酒成梦 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:44

    This is very easy to understand if you track class and instance dictionaries.

    class C:
       one = 42
       def __init__(self,val):
            self.two=val
    ci=C(50)
    print(ci.__dict__)
    print(C.__dict__)
    

    The result will be like this:

    {'two': 50}
    {'__module__': '__main__', 'one': 42, '__init__': <function C.__init__ at 0x00000213069BF6A8>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}
    

    Note I set the full results in here but what is important that the instance ci dict will be just {'two': 50}, and class dictionary will have the 'one': 42 key value pair inside.

    This is all you should know about that specific variables.

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

    I would like to add something to the responses that I read in this thread and this thread (which references this one).

    Disclaimer: this remarks come from the experiments I ran

    Variables outside __init__:

    These are, in fact, static class variables and are, therefore, accesible to all instances of the class.

    Variables inside __init__:

    The value of these instance variables are only accesible to the instance at hand (through the self reference)

    My contribution:

    One thing that programmers must consider when using static class variables is that they can be shadowed by instance variables (if you are accessing the static class variables through the self reference).

    Explanation:

    Previously, I thought that both ways of declaring the variables were exactly the same (silly me), and that was partly because I could access both kind of variables through the self reference. It was now, when I ran into trouble, that I researched the topic and cleared it up.

    The problem with accessing static class variables through the self reference is that it only references the static class variable if there is no instance variable with the same name, and to make things worse, trying to redefine a static class variable through the self reference does not work because an instance variable is created which then shadows the previously-accesible static class variable.

    To get around this problem, you should always reference static class variables through the name of the class.

    Example:

    #!/usr/bin/env python
    
    class Foo:
        static_var = 'every instance has access'
    
        def __init__(self,name):
            self.instance_var = 'I am %s' % name
    
        def printAll(self):
            print 'self.instance_var = %s' % self.instance_var
            print 'self.static_var = %s' % self.static_var
            print 'Foo.static_var = %s' % Foo.static_var
    
    f1 = Foo('f1')
    
    f1.printAll()
    
    f1.static_var = 'Shadowing static_var'
    
    f1.printAll()
    
    f2 = Foo('f2')
    
    f2.printAll()
    
    Foo.static_var = 'modified class'
    
    f1.printAll()
    f2.printAll()
    

    Output:

    self.instance_var = I am f1
    self.static_var = every instance has access
    Foo.static_var = every instance has access
    self.instance_var = I am f1
    self.static_var = Shadowing static_var
    Foo.static_var = every instance has access
    self.instance_var = I am f2
    self.static_var = every instance has access
    Foo.static_var = every instance has access
    self.instance_var = I am f1
    self.static_var = Shadowing static_var
    Foo.static_var = modified class
    self.instance_var = I am f2
    self.static_var = modified class
    Foo.static_var = modified class
    

    I hope this is helpful to someone

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

    further to S.Lott's reply, class variables get passed to metaclass new method and can be accessed through the dictionary when a metaclass is defined. So, class variables can be accessed even before classes are created and instantiated.

    for example:

    class meta(type):
        def __new__(cls,name,bases,dicto):
              # two chars missing in original of next line ...
              if dicto['class_var'] == 'A':
                 print 'There'
    class proxyclass(object):
          class_var = 'A'
          __metaclass__ = meta
          ...
          ...
    
    0 讨论(0)
  • 2020-11-22 17:48

    Example code:

    class inside:
        def __init__(self):
            self.l = []
    
        def insert(self, element):
            self.l.append(element)
    
    
    class outside:
        l = []             # static variable - the same for all instances
    
        def insert(self, element):
            self.l.append(element)
    
    
    def main():
        x = inside()
        x.insert(8)
        print(x.l)      # [8]
        y = inside()
        print(y.l)      # []
        # ----------------------------
        x = outside()
        x.insert(8)
        print(x.l)      # [8]
        y = outside()
        print(y.l)      # [8]           # here is the difference
    
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
提交回复
热议问题