2016-09-02 14 views
31

Tôi đã duyệt qua một số mã và tôi nhận thấy một dòng thu hút sự chú ý của tôi. Mã này cũng tương tự như ví dụ dưới đâyCó lý do nào để tự cung cấp giá trị mặc định không?

class MyClass: 
    def __init__(self): 
     pass 

    def call_me(self=''): 
     print(self) 

này trông giống như bất kỳ lớp khác mà tôi đã thấy, tuy nhiên một str đã được thông qua tại như giá trị mặc định cho self.

Nếu tôi in ra self, nó cư xử như bình thường

>>> MyClass().call_me() 
<__main__.MyClass object at 0x000002A12E7CA908> 

này đã được bugging tôi và tôi không thể tìm ra lý do tại sao điều này sẽ được sử dụng. Có bất kỳ lý do gì để giải thích tại sao một phiên bản str sẽ được chuyển thành một giá trị mặc định cho self?

+10

Có vẻ như có ai đó muốn có 'MyClass.call_me()' hoạt động. Không phải là một ý tưởng đặc biệt tốt, tuy nhiên, họ có thể đã làm cho nó một 'classmethod' thay thế. –

+0

Nếu 'call_me' được gọi từ chính lớp đó và không phải từ một cá thể, thì' '' 'được truyền như thể hiện, và cuộc gọi phương thức sẽ không gây ra lỗi. –

Trả lời

28

Không thực sự, nó chỉ là một lẻ cách làm cho nó không tăng một lỗi khi gọi thông qua các lớp:

MyClass.call_me() 

hoạt động tốt từ đó, mặc dù không có gì được mặc nhiên trôi qua như với trường hợp, giá trị mặc định cho đối số đó được cung cấp. Nếu không có mặc định đã được cung cấp, khi được gọi, điều này tất nhiên sẽ nâng cao TypeError cho args tất cả chúng ta yêu. Tại sao anh ta chọn một chuỗi rỗng làm giá trị, chỉ anh ấy biết.

Tóm lại, điều này là nhiều hơn gây nhầm lẫn so với thực tế.Nếu bạn cần phải làm một cái gì đó tương tự như tôi muốn tư vấn một đơn giản staticmethod với một đối số mặc định để đạt được một hiệu ứng tương tự.

Bằng cách đó bạn không Stump ai đọc mã của bạn (như các nhà phát triển người viết này đã làm với bạn ;-):

@staticmethod 
def call_me(a=''): 
    print(a) 

Nếu thay vào đó bạn cần truy cập vào lớp thuộc tính bạn có thể luôn luôn lựa chọn cho trang trí classmethod. Cả hai (classstatic trang trí) này cũng phục vụ mục đích thứ hai làm cho ý định của bạn rõ ràng với những người khác đọc mã của bạn.

13

Câu trả lời ngắn gọn là có. Bằng cách đó, bạn có thể gọi hàm này là:

MyClass.call_me() 

mà không cần instantiating MyClass, sẽ in một chuỗi rỗng.

Để đưa ra câu trả lời dài hơn, chúng ta cần xem xét những gì đang diễn ra đằng sau hậu trường.

Khi bạn tạo một thể hiện của lớp, __new____init__ được kêu gọi để tạo ra nó, đó là:

a = MyClass() 

được tương đương với:

a = MyClass.__new__(MyClass) 
MyClass.__init__(a) 

Bất cứ khi nào bạn sử dụng một số phương pháp trên một ví dụ được tạo a:

a.call_me() 

Nó được "thay thế" bằng MyClass.call_me(a).

Vì vậy, việc có thông số mặc định cho call_me cho phép bạn gọi hàm này không chỉ như một phương thức của một cá thể, trong trường hợp đó, self là một cá thể, mà còn là phương thức lớp tĩnh.

Bằng cách đó, thay vì MyClass.call_me(a), chỉ cần MyClass.call_me() được gọi. Vì danh sách đối số trống, đối số mặc định được gán cho self và kết quả mong muốn (chuỗi trống) được in.

Các vấn đề liên quan