2017-10-13 87 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 

變量等爲一體,六個被稱爲類變量。

類變量由用相同類創建的對象共享。