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

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

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


当前回答

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

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}')

其他回答

正如S.Lott所指出的,

在init之外设置的变量属于该类。它们由 所有实例。 在init(和所有其他方法函数)中创建的变量和 以自我开头。属于对象实例。

然而, 注意,类变量可以通过self访问。<var>,直到它们被一个具有类似名称的对象变量所掩盖。<var>在给它赋值之前将返回Class的值。<var>但之后它将返回obj。< var >。这里有一个例子

In [20]: class MyClass: 
    ...:     elem = 123 
    ...:  
    ...:     def update(self,i): 
    ...:         self.elem=i  
    ...:     def print(self): 
    ...:         print (MyClass.elem, self.elem) 
    ...:  
    ...: c1 = MyClass()  
    ...: c2 = MyClass() 
    ...: c1.print() 
    ...: c2.print()                                                                                                                                                                                                                                                               
123 123 
123 123 
In [21]: c1.update(1) 
    ...: c2.update(42) 
    ...: c1.print() 
    ...: c2.print()                                                                                                                                                                                                                                                               
123 1 
123 42
In [22]: MyClass.elem=22 
    ...: c1.print()  
    ...: c2.print()                                                                                                                                                                                                                                                               
22 1 
22 42

第二个注意事项:考虑插槽。它们可能提供了更好的实现对象变量的方法。

没有自我

创建一些对象:

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'

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

在__init__(以及所有其他方法函数)中创建并以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}')