2011-02-05 30 views
50

Đối với các lỗi:Thú vị 'mất chính xác 1 lập luận (2 nhất định)' Python lỗi

TypeError: takes exactly 1 argument (2 given) 

Với phương pháp lớp sau đây:

def extractAll(tag): 
    ... 

và gọi đó là:

e.extractAll("th") 

Lỗi này có vẻ rất kỳ quặc khi tôi đưa ra 1 đối số, phương thức này chỉ lấy 1 đối số, nhưng nó nói rằng tôi không đưa ra 1 đối số. ... Tôi biết vấn đề có thể được sửa bằng cách thêm self vào nguyên mẫu phương pháp nhưng tôi muốn biết lý do đằng sau lỗi.

Tôi nhận được nó bởi vì hành động gọi nó qua e. extractAll ("th") cũng vượt qua trong self làm đối số? Và nếu vậy, bằng cách loại bỏ các self trong cuộc gọi, tôi sẽ làm cho nó một số loại phương pháp lớp có thể được gọi là Extractor.extractAll("th")?

Trả lời

73

Cuộc gọi

e.extractAll("th") 

cho một phương pháp thường xuyên extractAll() thực sự là tương đương với

Extractor.extractAll(e, "th") 

Hai cuộc gọi được đối xử như nhau trong tất cả các liên quan, bao gồm cả các thông báo lỗi bạn nhận được.

Nếu bạn không cần phải vượt qua dụ đến một phương pháp, bạn có thể sử dụng một staticmethod:

@staticmethod 
def extractAll(tag): 
    ... 

mà có thể được gọi là e.extractAll("th"). Nhưng tôi tự hỏi tại sao đây là một phương thức trên một lớp nếu bạn không cần truy cập vào bất kỳ cá thể nào.

+0

nó hợp lý để có phương pháp này trong một lớp nếu tôi cần phải truy cập các lĩnh vực của lớp phải không? ... –

+0

@ funk-shun: Phải, nhưng hơn bạn sẽ cần một 'classsmethod', không phải là một' staticmethod'. Và thông thường, tôi sẽ chỉ sử dụng một phương pháp thông thường cho loại phương pháp này. –

+0

@ user2533809: Thông thường, tham số đầu tiên của 'classmethod' được gọi là' cls', bởi vì nó là chính lớp đó, không phải là một thể hiện của nó. –

3

Có, khi bạn gọi e.extractAll(foo), Python sẽ chuyển thành extractAll(e, foo).

Từ http://docs.python.org/tutorial/classes.html

the special thing about methods is that the object is passed as the first argument of the function. In our example, the call x.f() is exactly equivalent to MyClass.f(x). In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s object before the first argument.

Nhấn mạnh thêm.

8

Am I getting it because the act of calling it via e.extractAll("th") also passes in self as an argument?

Vâng, chính xác là như vậy. Nếu bạn thích, tham số đầu tiên là tên đối tượng, e mà bạn đang gọi nó.

And if so, by removing the self in the call, would I be making it some kind of class method that can be called like Extractor.extractAll("th")?

Không hoàn toàn. Một classmethod cần trang trí @classmethod và chấp nhận lớp làm paramater đầu tiên (thường được tham chiếu là cls). Kiểu duy nhất của phương thức không có tham số tự động nào được gọi là staticmethod, và lại cần một trình trang trí (không ngạc nhiên, nó là @staticmethod). Một classmethod được sử dụng khi nó là một hoạt động mà cần phải tham khảo chính lớp đó: có lẽ là các đối tượng instantiating của lớp; staticmethod được sử dụng khi mã nằm trong lớp logic, nhưng không yêu cầu quyền truy cập vào lớp hoặc cá thể.

Nhưng có, cả staticmethods và classmethods có thể được gọi bằng cách tham chiếu tên lớp như bạn mô tả: Extractor.extractAll("th").

+1

Cả hai đều tương đối hiếm trong mã python được viết tốt. Nếu bạn nghĩ rằng bạn cần phải sử dụng chúng ngay lập tức, tôi đề nghị bạn xem xét lại cho dù nó cần phải được bên trong một lớp học ở tất cả. Có lẽ bạn đang cố gắng viết Java với python. – chmullig

+1

Tôi thích sử dụng classmethod như các phương thức factory: nó làm cho nó rõ ràng loại đối tượng đang được tạo ra. –

25

Nếu một phương pháp không tĩnh là thành viên của một lớp, bạn phải xác định nó như thế:

def Method(self, atributes..) 

Vì vậy, tôi cho rằng 'e' của bạn là thể hiện của một số lớp học với phương pháp thực hiện mà cố gắng để thực thi và có quá nhiều đối số.

1

hãy thử sử dụng:

def extractAll(self,tag): 

ý đến tự

3

Tóm tắt (Một số ví dụ về làm thế nào để xác định phương pháp trong các lớp học trong python)

#!/usr/bin/env python # (if running from bash) 

class Class1(object): 

    def A(self, arg1): 
     print arg1 
     # this method requires an instance of Class1 
     # can access self.variable_name, and other methods in Class1 

    @classmethod 
    def B(cls, arg1): 
     cls.C(arg1) 
     # can access methods B and C in Class1 

    @staticmethod 
    def C(arg1): 
     print arg1 
     # can access methods B and C in Class1 
     # (i.e. via Class1.B(...) and Class1.C(...)) 

Ví dụ

my_obj=Class1() 

my_obj.A("1") 
# Class1.A("2") # TypeError: method A() must be called with Class1 instance 

my_obj.B("3") 
Class1.B("4") 
my_obj.C("5") 
Class1.C("6")` 
Các vấn đề liên quan