2012-02-10 32 views
5

Ý tưởng cơ bản của những gì tôi muốn làm là:Làm thế nào để có các kiểu đầu vào khác nhau cho cùng một chức năng?

def aFuncion(string = '', dicti = {}): 
    if len(str) > 0: 
     print 'you gave string as input' 
    if len(dicti) > 0: 
     print 'you gave a dict as input' 

aFunction(string = 'test') 
dict['test'] = test 
aFunction(dicti = dict) 

tôi biết loại này ý tưởng là có thể có trong nhiều loại OO của ngôn ngữ, nhưng là điều này cũng có thể trong python?

Ngay bây giờ tôi đang làm

def aFuncion(input): 
    if type(input) == str: 
     print 'you gave string as input' 
    if type(input) == dict: 
     print 'you gave a dict as input' 

aFunction('test') 

Nhưng tôi muốn sự khác biệt rõ ràng khi hàm được gọi

Trả lời

3

Mục tiêu này muốn "sự khác biệt rõ ràng khi hàm được gọi" không chà xát tốt với triết lý thiết kế của ngôn ngữ. Google "gõ vịt" để biết thêm thông tin về điều đó. Các đầu vào được chấp nhận phải được làm rõ bằng docstring của hàm, và đó là tất cả những gì bạn cần làm.

Trong trăn, khi bạn muốn đầu vào của nó là một chuỗi hoặc một dict, thì bạn chỉ cần viết mã giả định đầu vào sẽ là một đối tượng cư xử theo cách giống như chuỗi hoặc cách dict . Nếu đầu vào không, sau đó bạn có thể cố gắng xử lý một cách duyên dáng nếu bạn muốn, nhưng thông thường bạn có thể chỉ cần để lại mã của bạn chỉ cần bật với một ngoại lệ chưa được xử lý. Điều này đặt bóng trở lại trong tòa án của người gọi để quyết định cách xử lý tình huống hoặc nhận ra rằng họ đang gửi dữ liệu xấu.

Kiểm tra loại cần tránh nói chung, nếu thực sự cần thiết, nó nên được thực hiện với isinstance thay vì kiểm tra bình đẳng về loại như bạn đã làm. Điều này có lợi thế là linh hoạt hơn cho các tình huống thừa kế.

def aFuncion(input_): 
    if isinstance(input_, str): 
     print 'you gave a string-like input' 
    elif isinstance(input_, dict): 
     print 'you gave a dict-like input' 

aFunction('test') 

Trong python3 bây giờ bạn có tùy chọn khác sử dụng chú thích hàm gợi ý loại. Đọc PEP 484 để biết thêm chi tiết về tính năng đó.

+0

+1 Điểm tốt về triết lý ngôn ngữ. Plus, tôi tin rằng bạn nên thay đổi tên của đối số 'input' (bây giờ nó sẽ ghi đè lên một hàm dựng sẵn). – Tadeck

6

Ý tưởng của việc có sự hỗ trợ cùng một phương pháp loại đối số khác nhau được gọi là multiple dispatch or multimethods.

Để có được một giới thiệu tốt về nó, bạn có thể đọc Guido Van Rossum article và có một cái nhìn tại PyPi vì có một vài multimethod packages có sẵn.

+0

Cảm ơn, tôi không biết tên (đang xem xét đa hình) sẽ giúp –

0

Những gì bạn có cơ bản hoạt động, chỉ có một số rắc rối với các khai báo biến. Đây là một vesrion làm việc:

def aFunction(str = '', dicti = {}): 
    if len(str) > 0: 
     print 'you gave string as input' 
    if len(dicti) > 0: 
     print 'you gave a dict as input' 

str = 'test' 
dicti = dict([('test', 'test')]) 
aFunction(str = str) 
aFunction(dicti = dicti) 
aFunction(str = str, dicti = dicti) 
aFunction(dicti = dicti, str = str) 

puts:

you gave string as input 
you gave a dict as input 
you gave string as input 
you gave a dict as input 
you gave string as input 
you gave a dict as input 

Bạn cũng có thể có đối số không đặc hiệu được gửi đến các chức năng như cả một danh sách và một cuốn từ điển (xem What is a clean, pythonic way to have multiple constructors in Python? ví dụ).

+0

Câu trả lời của bạn sai. Bạn vẫn có thể gọi 'aFunction' với:' aFunction ([1,2,3]) 'và nó sẽ giả định rằng bạn đã cho nó một chuỗi (rõ ràng không phải là trường hợp) cũng như' aFunction (dicti = " đây không phải là một dict ")" và nó sẽ giả sử bạn nhập vào một dict. @wim có câu trả lời đúng, sử dụng cách gõ vịt. Gán một đối số mặc định cho một kiểu đã cho, sẽ không cung cấp cho bạn sự đảm bảo, vì Python là một ngôn ngữ đánh máy yếu và nó có thể thay đổi khi chạy. –

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