除了名字以外,这些类之间有什么不同吗?

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__方法来声明变量值,会有任何区别吗?

我主要担心的是,我只会以一种方式使用它,而这会给我带来更多的问题。


当前回答

在__init__之外设置的变量属于类。它们由所有实例共享。

在__init__(以及所有其他方法函数)中创建并以self为前缀的变量。属于对象实例。

其他回答

我想对我在这个帖子和这个帖子(引用了这个帖子)中读到的回复添加一些东西。

免责声明:这些评论来自我进行的实验

__init__之外的变量:

实际上,这些是静态类变量,因此类的所有实例都可以访问它们。

__init__中的变量:

这些实例变量的值只能被手边的实例访问(通过自引用)

我的贡献:

程序员在使用静态类变量时必须考虑的一件事是,它们可能被实例变量所掩盖(如果您通过自引用访问静态类变量)。

解释:

以前,我认为声明变量的两种方式是完全相同的(我真傻),这部分是因为我可以通过自我引用访问这两种变量。就是现在,当我遇到麻烦时,我研究了这个话题,并把它弄清楚了。

类访问静态类变量的问题 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

我希望这对某些人有所帮助

没有自我

创建一些对象:

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'

示例代码:

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()

试试这个,看看有什么不同

class test:
    f = 3

    def __init__(s, f):
        s.__class__.f = f
        s.f = s.__class__.f
        print(f'def __init__(s, {f})')
        print(f's.__class__.f = {f}')
        print(f's.f={s.__class__.f}')
        print(f'f={f}')
        print('===============init over===========')

    def setinstancetoOne(s, f):
        print(f'def setinstancetoOne(s, {f})')
        s.f = f

    print(f'class var f = {f}')

    def useClassname(test):
        print(f'>>>>def useClassname({test})')
        print(f'test.f {test.f}')

    def p_method(s):
        print(f'>>>>def p_method({s})')
        print(f's.f {s.f}')
        print(f'test.f {test.f}')
        print(f's.__class__.f {s.__class__.f}')

    print(f'class var f={f}')


# test.__init__.f = 19
t = test(2)
t.useClassname()
t.p_method()
print(f'Outside class t.f {t.f}')
print(f'Outside class test.f {test.f}')

print('______difference__________')
t = test(2)
t.setinstancetoOne(1)
t.useClass()
t.p_method()
print(f'Outside class instance variable(2) {t.f}')
print(f'Outside class class variable(3) {test.f}')
class foo(object):
    mStatic = 12

    def __init__(self):
        self.x = "OBj"

考虑到foo根本无法访问x(事实)

现在的冲突是通过实例或直接通过类访问mStatic。

从Python内存管理的角度来考虑:

12的值在内存中,名称mStatic(可以从类中访问)

指向它。

c1, c2 = foo(), foo() 

这一行创建了两个实例,其中包括指向值12的名称mStatic(到目前为止)。

foo.mStatic = 99 

这使得mStatic name指向内存中值为99的新位置。

因为(婴儿)c1 c2仍然在(爸爸)foo后面,所以它们有相同的名字(c1。mStatic & c2。mStatic)指向相同的新值。

但一旦每个宝宝决定独自走路,情况就不同了:

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

从现在到以后,该家族中的每一个(c1,c2,foo)都有它的mStatica指向不同的值。

[请尝试使用id()函数为所有(c1,c2,foo)在不同的状态,我们谈到,我认为这将使事情更好]

这就是我们真实的生活。儿子从父亲那里继承了一些信仰,这些信仰在儿子决定改变之前仍然与父亲的信仰相同。

希望对大家有所帮助