2014-04-25 13 views
29

Tôi khá mới để trăn, và nhận thấy những bài viết: Python __init__ and self what do they do?Python Classes without using def __init__(self)Tính hữu ích của def __init __ (tự)?

Sau khi chơi đùa với nó, tuy nhiên, tôi nhận thấy rằng hai loại cổ phiếu này cho rõ ràng tương đương results-

class A(object): 
    def __init__(self): 
     self.x = 'Hello' 

    def method_a(self, foo): 
     print self.x + ' ' + foo 

(từ this question)

class B(object): 
    x = 'Hello' 
    def method_b(self,foo): 
     print self.x + ' ' + foo 

Có sự khác biệt thực sự nào giữa hai loại này không? Hoặc, nói chung, không __init__ có thay đổi bất kỳ thứ gì vốn có về các thuộc tính của một lớp không? Trong the documentation nó được đề cập rằng __init__ được gọi khi cá thể được tạo ra. Điều này có nghĩa là x trong lớp B được thiết lập trước khi khởi tạo?

Trả lời

32

Yeah, kiểm tra này:

class A(object): 
    def __init__(self): 
     self.lst = [] 

class B(object): 
    lst = [] 

và bây giờ thử:

>>> x = B() 
>>> y = B() 
>>> x.lst.append(1) 
>>> y.lst.append(2) 
>>> x.lst 
[1, 2] 
>>> x.lst is y.lst 
True 

và điều này:

>>> x = A() 
>>> y = A() 
>>> x.lst.append(1) 
>>> y.lst.append(2) 
>>> x.lst 
[1] 
>>> x.lst is y.lst 
False 

Điều này có nghĩa rằng x trong lớp B được thành lập trước khi instantiation?

Vâng, đó là thuộc tính lớp (được chia sẻ giữa các phiên bản). Trong khi ở lớp A nó là một thuộc tính instance. Nó chỉ xảy ra rằng các chuỗi là không thay đổi, do đó không có sự khác biệt thực sự trong kịch bản của bạn (ngoại trừ lớp B sử dụng ít bộ nhớ hơn, vì nó chỉ định nghĩa một chuỗi cho tất cả các cá thể). Nhưng có một ví dụ lớn trong ví dụ của tôi.

+2

+1 Đừng quên rằng kể từ khi lớp học các đối tượng bạn có thể thay đổi thuộc tính của lớp, chính nó, bất cứ lúc nào. 'class A: pass; A.lst = list (phạm vi (6))'. – kojiro

9

Trong ví dụ đầu tiên bạn có biến thể hiện của lớp. Biến này chỉ có thể truy cập thông qua một cá thể (tự yêu cầu).

class A(): 
    def __init__(self): 
     self.x = 'hello' 

print A.x -> AttributeError 
print A().x -> 'hello' 

Trong ví dụ thứ hai, bạn có biến tĩnh. Bạn có thể truy cập vào này biến nhờ vào tên của lớp Một

class A(): 
    x = 'hello' 

print A.x -> 'hello' 
print A().x -> 'hello' 

Trong thực tế, bạn có thể có một biến tĩnh và một biến Ví dụ có cùng tên:

class A(): 
    x = 'hello' 
    def __init__(self): 
     self.x = 'world' 

print A.x -> hello 
print A().x -> world 

Giá trị tĩnh được chia sẻ giữa tất cả các trường hợp

class A(): 
    x = 'hello' 

    @staticmethod 
    def talk(): 
     print A.x 

a = A() 
print a.talk() -> hello 

A.x = 'world' 
print a.talk() -> world 

Bạn có một bài viết tốt ở đây: http://linuxwell.com/2011/07/21/static-variables-and-methods-in-python/

4

Như những người khác đã nêu, đó là sự khác biệt giữa một biến trên một lớp và một biến trên một lớp dụ. Xem ví dụ sau.

>>> class A: 
...  a = [] 
... 
>>> class B: 
...  def __init__(self): 
...   self.b = [] 
... 
>>> a1 = A() 
>>> a1.a.append('hello') 
>>> a2 = A() 
>>> a2.a 
['hello'] 
>>> b1 = B() 
>>> b1.b.append('goodbye') 
>>> b2 = B() 
>>> b2.b 
[] 

Đối với đối tượng bất biến như tuples, chuỗi, vv nó khó khăn hơn để nhận thấy sự khác biệt, nhưng đối với mutables, nó thay đổi tất cả mọi thứ — những thay đổi áp dụng được chia sẻ giữa tất cả các trường của lớp đó.

Cũng lưu ý rằng hành vi tương tự xảy ra đối với mặc định đối số từ khóa!

>>> class A: 
...  def __init__(self, a=[]): 
...   a.append('hello') 
...   print(a) 
... 
>>> A() 
['hello'] 
>>> A() 
['hello', 'hello'] 
>>> A() 
['hello', 'hello', 'hello'] 

>>> class B: 
...  def __init__(self, b=None): 
...   if b is None: 
...    b = [] 
...   b.append('goodbye') 
...   print(b) 
... 
>>> B() 
['goodbye'] 
>>> B() 
['goodbye'] 
>>> B() 
['goodbye'] 

Hành vi này cắn rất nhiều lập trình viên Python mới. Tốt cho bạn trong việc khám phá những khác biệt này sớm!

0

bạn sử dụng init bạn không cần phải sử dụng nó trong trường hợp của bạn, bạn có thể chỉ

enter code here 

class some(): 
    def main(self): 
     self.x=10 
    def mathod_a(self,foo): 
     print self.x+foo' 

và nếu bạn muốn sử dụng init thử nó

enter code here 
class some(): 
def main(self): 
    print(x) 
def init(self,x): 
    self.x=x 
    main() 
Các vấn đề liên quan