2009-05-11 28 views
101

Làm cách nào để tìm số đối số của hàm Python? Tôi cần phải biết có bao nhiêu đối số bình thường và có bao nhiêu đối số được đặt tên.Làm cách nào tôi có thể tìm số đối số của hàm Python?

Ví dụ:

def someMethod(self, arg1, kwarg1=None): 
    pass 

Phương pháp này có 2 đối số và 1 tên đối số.

+2

Tôi đang triển khai hệ thống thông báo, không thực sự biết trước số lượng đối số mà người nhận muốn. (Thông thường là tất cả hoặc không có.) –

+39

câu hỏi được bảo hành đầy đủ; nếu nó không phải (vì bạn luôn có thể đọc nguồn), sẽ không có bất kỳ biện minh nào cho mô-đun thư viện chuẩn 'kiểm tra'. – flow

+0

Rất nhiều ngôn ngữ triển khai ít nhất một tính năng không được điều chỉnh. Mô-đun 'kiểm tra' có rất nhiều tính năng khác, do đó, không công bằng khi nói rằng toàn bộ mô-đun sẽ không được điều chỉnh nếu một hàm cụ thể trong đó. Hơn nữa, thật dễ dàng để xem tính năng này có thể được sử dụng kém như thế nào. (Xem http://stackoverflow.com/questions/741950). Điều đó nói rằng, nó là một tính năng hữu ích, đặc biệt là để viết trang trí và các chức năng khác hoạt động trên chức năng. – user1612868

Trả lời

43

Câu trả lời được chấp nhận trước đó đã được deprecated như của Python 3.0. Thay vì sử dụng inspect.getargspec, bạn nên chọn lớp học Signature thay thế nó.

Tạo Chữ ký cho chức năng rất dễ dàng thông qua signature function:

from inspect import signature 

def someMethod(self, arg1, kwarg1=None): 
    pass 

sig = signature(someMethod) 

Bây giờ, bạn có thể xem các thông số của nó một cách nhanh chóng bởi str ing nó:

str(sig) # returns: '(self, arg1, kwarg1=None)' 

hoặc bạn cũng có thể nhận được một ánh xạ tên thuộc tính cho đối tượng tham số qua sig.parameters.

params = sig.parameters 
print(params['kwarg1']) # prints: kwarg1=20 

Ngoài ra, bạn có thể gọi len trên sig.parameters còn nhìn thấy số lượng đối số chức năng này đòi hỏi:

print(len(params)) # 3 

Mỗi mục trong bản đồ params thực sự là một Parameter object có thuộc tính thêm làm cho cuộc sống của bạn dễ dàng hơn. Ví dụ: việc lấy thông số và xem giá trị mặc định của nó giờ đây có thể dễ dàng được thực hiện với:

tương tự cho các đối tượng còn lại trong parameters.


Đối với Python 2.x người dùng, trong khi inspect.getargspeckhông bị phản đối, ngôn ngữ sẽ sớm được :-). Lớp học Signature không khả dụng trong chuỗi 2.x và sẽ không khả dụng. Vì vậy, bạn vẫn cần phải làm việc với inspect.getargspec.

Đối với chuyển giữa Python 2 và 3, nếu bạn có mã dựa trên giao diện của getargspec bằng Python 2 và chuyển sang signature trong 3 là quá khó khăn, bạn có tùy chọn có giá trị của việc sử dụnginspect.getfullargspec. Nó cung cấp một giao diện tương tự như getargspec (một cuộc tranh luận có thể được gọi duy nhất) để lấy các đối số của một hàm trong khi cũng xử lý một số trường hợp bổ sung mà getargspec không:

from inspect import getfullargspec 

def someMethod(self, arg1, kwarg1=None): 
    pass 

args = getfullargspec(someMethod) 

Như với getargspec, getfullargspec trả về một NamedTuple mà chứa các đối số.

print(args) 
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={}) 
+1

Cảm ơn bạn đã viết một câu trả lời mới cho một câu hỏi cũ, điều này thật tuyệt vời! –

+0

Bạn được chào đón @ GeorgSchölly. Tôi đã ngạc nhiên một câu hỏi phổ biến như thế này cung cấp các giải pháp hoặc là không được chấp nhận hoặc xuống quyền lén lút (nhìn trộm trong thuộc tính 'co_argcount'.) –

+0

' getfullargspec' không được thực hiện trong Python 2.x, bạn cần sử dụng 'getargspec' –

114
import inspect 
inspect.getargspec(someMethod) 

thấy the inspect module

+4

Nói chung những gì bạn muốn, nhưng điều này không làm việc cho các chức năng tích hợp. Cách duy nhất để biết để có được thông tin này cho nội trang là phân tích cú pháp chuỗi __doc__ của chúng, điều này là khéo léo nhưng có thể thực hiện được. – Cerin

+3

Điều này không còn được dùng trong Python 3: https://docs.python.org/3/library/inspect.html#inspect.getargspec – noisecapella

+0

Có một giải pháp không được dùng trong Python 3 không? – hlin117

16

inspect.getargspec()

Get the names and default values of a function’s arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). args is a list of the argument names (it may contain nested lists). varargs and varkw are the names of the * and ** arguments or None. defaults is a tuple of default argument values or None if there are no default arguments; if this tuple has n elements, they correspond to the last n elements listed in args.

Changed in version 2.6: Returns a named tuple ArgSpec(args, varargs, keywords, defaults).

Xem can-you-list-the-keyword-arguments-a-python-function-receives.

25
someMethod.func_code.co_argcount 

hoặc, nếu tên hàm hiện tại không được xác định:

import sys 

sys._getframe().func_code.co_argcount 
+0

+1, bạn nhận được từ đâu? – elyase

+4

@elyase, chỉ cần làm: 'dir (someMethod)' -> ''func_code''; Đi xa hơn: 'dir (someMethod.func_code)' -> ''co_argcount''; Bạn có thể sử dụng 'dir()' có sẵn để xác định các phương thức có sẵn của một đối tượng. –

+0

@elyase Tôi cũng rất nổi tiếng, vì vậy tôi đã tìm thấy https://docs.python.org/2/library/inspect.html#types-and-members – rodripf

3

Thêm vào bên trên, Tôi cũng thấy rằng hầu hết các lần giúp đỡ() chức năng thực sự giúp

Ví dụ, nó cung cấp tất cả các chi tiết về các đối số cần.

help(<method>) 

đưa ra dưới đây

method(self, **kwargs) method of apiclient.discovery.Resource instance 
Retrieves a report which is a collection of properties/statistics for a specific customer. 

Args: 
    date: string, Represents the date in yyyy-mm-dd format for which the data is to be fetched. (required) 
    pageToken: string, Token to specify next page. 
    parameters: string, Represents the application name, parameter name pairs to fetch in csv as app_name1:param_name1, app_name2:param_name2. 

Returns: 
    An object of the form: 

    { # JSON template for a collection of usage reports. 
    "nextPageToken": "A String", # Token for retrieving the next page 
    "kind": "admin#reports#usageReports", # Th 
+0

Sẽ tốt cho mọi người để lại nhận xét về những gì sai với một bài đăng hơn là chỉ cần nhấp vào nút dấu trừ. Hàm –

+2

'help' chỉ hiển thị những gì mà docstring nói. Thậm chí bạn đã kiểm tra xem nó có hoạt động với định nghĩa hàm trong câu hỏi không? – 0xc0de

+0

@ 0xc0de - Bạn đã thử nghiệm chưa? Bởi vì nó thực sự hoạt động. 'help()' spits ra nhiều hơn chỉ là docstring - ngay cả trên mã không có giấy tờ, nó vẫn in ra argspec và cho bạn biết mã được định nghĩa ở đâu. Người đăng câu hỏi ban đầu không rõ liệu họ có cần câu trả lời thân thiện với người hay máy móc hay không. Nếu nó chỉ cần thân thiện với con người, 'help()' là hoàn toàn phù hợp. – ArtOfWarfare

1

Như các câu trả lời khác đề xuất, getargspec hoạt động tốt miễn là điều được truy vấn thực sự là một chức năng. Nó không làm việc cho built-in chức năng như open, len, vv, và sẽ ném một ngoại lệ trong trường hợp này:

TypeError: <built-in function open> is not a Python function 

Hàm dưới đây (lấy cảm hứng từ this answer) chứng tỏ một workaround. Nó trả về số args mong đợi bởi f:

from inspect import isfunction, getargspec 
def num_args(f): 
    if isfunction(f): 
    return len(getargspec(f).args) 
    else: 
    spec = f.__doc__.split('\n')[0] 
    args = spec[spec.find('(')+1:spec.find(')')] 
    return args.count(',')+1 if args else 0 

Ý tưởng là để phân tích các chức năng đặc tả ra khỏi __doc__ chuỗi. Rõ ràng điều này phụ thuộc vào định dạng của chuỗi đã nói nên khó thực sự mạnh mẽ!

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