2017-10-13 74 views
5

我对编程非常陌生。我刚刚开始了几个星期。我花了几个小时阅读课程,但我仍然困惑。我有一个具体的问题。python __init__ vs类属性

我对何时使用类属性以及何时使用初始值设定项(__init__)感到困惑。

据我所知,当使用__init__时,我没有立即分配任何值,但只需要在使用该类创建对象时分配值。并且类属性自动为该类下创建的对象所固有。

但在实际使用方面,他们是否完成了同样的事情?他们只是两种不同的方式来做同样的事情吗?或者是__init__做了那些class属性不能做的事情?

我对这些代码进行了一些测试,结果是一样的。我很困惑什么时候用哪个。对我来说class属性看起来更方便使用。

#use class attributes for class Numbers_1 
class Numbers_1: 

    one = 1 
    two = 2 
    three = 3 
    six = two * three 

def multiply(self): 
    return self.six * self.two * self.three 

#use initializer for class Numbers_2  
class Numbers_2: 

def __init__(self, num10, num20, num30, num600): 
    self.num10 = num10 
    self.num20 = num20 
    self.num30 = num30 
    self.num600 = num600 

def multiply(self): 
    return self.num600 * self.num20 * self.num30 

#Now I run some test to compare the two classes... 
x = Numbers_1() 
y = Numbers_2(10, 20, 30, 20*30) 

print(x.one)  #print 1 
print(y.num10) #print 10 

print(x.six)  #print 6 
print(y.num600) #print 600 

#assign attributes to each objects 
x.eighteen = x.six * x.three 
y.num18000 = y.num600 * y.num30 

print(x.eighteen) #print 18 
print(y.num18000) #print 18000 

#try printing methods in each object 
print(x.multiply()) #print 36 
print(y.multiply()) #print 360000 

#try reassign values to attributes in each object 
x.one = 100 
y.num10 = 1000 

print(x.one)  #prints 100 
print(y.num10) #prints 1000 
+0

需要注意的一件事是** first.class = 2 **在您的第一个类的实例重新绑定到该实例的名称空间的“一个”,因此此共享变量说话_seems_不正确。玩弄可变变量,如追加以获得更好的事物感觉。在类级别声明并在实例中重写是为不可变变量设置默认值的好方法。 –

+0

我的意思是说“追加到一个类级别列表变量”上面。 –

回答

3

你得到的一切权利 - 除了类属性也起到像蟒蛇静态变量。

但是,请注意,类解析器在解析时立即运行

# file1.py 
def foo(): 
    print("hello world") 

class Person: 
    first_name = foo() 
    last_name = None 

    def __init__(self): 
     last_name = "augustus" 
     print("good night") 

# file2.py 
import file1 
>>> "hello world" 
x = Person() 
>>> "good night" 
1

类属性不是对象特定的。例如:

x = Numbers_1() 
y = Numbers_1() 

在上面,x和y将具有相同的类属性。

相反,init函数定义了对象属性。例如:

s = Numbers_2(10, 20, 30, 20*30) 
t = Numbers_2(11, 21, 31, 21*31) 

s和t现在具有不同的对象属性。

2

要了解这些差异,您需要考虑这些类别的类别实例之间的差异。

类属性适用于该类的对象。修改它们将修改该类的所有实例。修改实例属性只会修改正在操作的特定对象。

例如:

class Foo: 
    class_var = 'bar' 
    def __init__(self): 
     self.instance_var = 'baz' 
foo1 = Foo() 
foo2 = Foo() 

print(foo1.class_var, foo2.class_var) 
print(foo1.instance_var, foo2.instance_var) 

Foo.class_var = 'quux' 
Foo.instance_var = "this doesn't work" 
foo1.instance_var = 'this does' 


print(foo1.class_var, foo2.class_var) 
print(foo1.instance_var, foo2.instance_var) 

打印

bar bar 
baz baz 
quux quux 
this does baz 

因此,修改Foo.class_var取代的Fooclass_var所有现有的情况下,同时修改Foo.instance_var什么都不做。在对象上修改instance_var的类型Foo,但是,确实是工作,但仅限于该特定实例 - 其他实例未更改。

2

如果创建了多个对象,你可以看到其中的差别

class Numbers_1: 

    one = 1 
    two = 2 
    six = one * two 

    def __init__(self, o, t): 
    self.o = o 
    self.t = t 

    def mul(self): 
    return self.o * self.t 

o1 = Numbers_1(1, 2) 
o2 = Numbers_1(10, 20) 
o3 = Numbers_1(20, 30) 

print(o1.six) # 2 
print(o2.six) # 2 
print(o3.six) # 2 

print(o1.mul()) # 2 
print(o2.mul()) # 200 
print(o3.mul()) # 600 

变量等为一体,六个被称为类变量。

类变量由用相同类创建的对象共享。