内部和一类__init __的外侧()函数变量内部和一类__init __的外侧()函数变量(Var

2019-05-06 11:02发布

我想知道,有没有在所有的除了名字,这些类之间有什么区别? 这有什么区别,如果我使用或不使用__init __()函数在声明变量“值”?

class WithClass ():
    def __init__(self):
        self.value = "Bob"
    def my_func(self):
        print(self.value)

class WithoutClass ():
    value = "Bob"

    def my_func(self):
        print(self.value)

我主要担心的是,我将使用的一种方式时会导致我的问题之路越走越(目前我使用init调用)。

Answer 1:

变量设置外__init__属于类。 他们由所有实例共享。

内部创建的变量__init__ (以及所有其它方法的功能)中,用开头self. 属于对象实例。



Answer 2:

没有自我

创建一些对象:

class foo(object):
    x = 'original class'

c1, c2 = foo(), foo()

我可以改变C1情况下,也不会影响到C2的实例:

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

但是,如果我改变Foo类,该类的所有实例将被改变,以及:

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

请注意Python的作用域是如何在这里工作:

c1.x
>>> 'changed instance'

随着自

更改类不会影响实例:

class foo(object):
    def __init__(self):
        self.x = 'original self'

c1 = foo()
foo.x = 'changed class'
c1.x
>>> 'original self'


Answer 3:

我想的东西添加到我在这个线程和读取响应这个线程 (引用这一项)。

免责声明 :此言论来自我跑的实验

外变量__init__

这些,事实上, 静态类变量 ,并且因此,入店到类的所有实例。

内部变量__init__

这些实例变量的值仅是入店到实例在手(通过self参考)

我的贡献

使用静态类变量时,程序员必须考虑的一件事是,他们可以通过实例变量被隐藏(如果您是通过访问静态类变量 self基准)。

说明

以前,我认为声明的变量两种方式都是一模一样的(愚蠢的我),那部分是因为我可以通过访问这两种类型的变量self参考。 这是现在,当我遇到了麻烦,我研究的主题,并清除它。

与通过访问静态类变量的问题self引用如果具有相同名称的实例变量 ,而更糟糕的是,试图通过重新定义静态变量 ,它仅引用静态类变量 self引用不工作,因为实例变量被创建,然后阴影先前入店静态类变量

为了解决这个问题,你应该总是通过类的名称引用静态类变量

例如

#!/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()

输出

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

我希望这是有帮助的人



Answer 4:

继美国洛特的答复,类变量会马上传递给元类新的方法和可以通过字典来访问定义元类时。 因此,类变量可以被创建和实例化甚至之前类访问。

例如:

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
      ...
      ...


Answer 5:

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)

在上面的代码中,用户类具有3个全局变量,每个的值是“无”。 U1是通过实例化此类创建的对象。 print_var打印对象U1的类用户和对象变量的类变量的值的方法。 在下面所示的输出,每一个类变量的User.emailUser.firstnameUser.lastname具有值'none' ,则在对象的变量u1.emailu1.firstnameu1.lastname具有值'abc@xyz''first''last'

obj.email obj.firstname obj.lastname
('abc@xyz', 'first', 'last')
cls.email cls.firstname cls.lastname
('none', 'none', 'none')


文章来源: Variables inside and outside of a class __init__() function
标签: python class