2010-01-03 27 views
250

Có cách nào để mở rộng một bộ torrent Python thành một hàm - như các tham số thực tế?Mở rộng các tuple thành các đối số

Ví dụ, đây expand() làm sự kỳ diệu:

tuple = (1, "foo", "bar") 

def myfun(number, str1, str2): 
    return (number * 2, str1 + str2, str2 + str1) 

myfun(expand(tuple)) # (2, "foobar", "barfoo") 

Tôi biết người ta có thể xác định myfun như myfun((a, b, c)), nhưng tất nhiên có thể có mã di sản. Cảm ơn

Trả lời

486

myfun(*tuple) không chính xác chính xác những gì bạn yêu cầu.

Side phát hành: không sử dụng như là định danh của bạn được xây dựng trong tên kiểu như tuple, list, file, set, và vân vân - đó là thực tế kinh khủng và nó sẽ trở lại và cắn bạn khi bạn ít mong đợi nó, do đó, chỉ cần tham gia thói quen tích cực tránh ẩn tên nội trang có số nhận dạng của riêng bạn.

+1

Bạn có thể vui lòng cung cấp giải thích tại sao toán tử asteriks thực hiện những gì được yêu cầu không? – winklerrr

+1

Toán tử * chỉ đơn giản là bỏ gói tuple và chuyển chúng thành các đối số vị trí cho hàm. Xem thêm tại đây: https://docs.python.org/3/tutorial/controlflow.html#tut-unpacking-arguments –

+0

Lưu ý rằng cùng một cú pháp có thể được sử dụng cho các danh sách cũng như các bộ dữ liệu. –

12

Hãy xem the Python tutorial phần 4.7.3 và 4.7.4. Nó nói về việc chuyển các bộ dữ liệu làm đối số.

Tôi cũng sẽ xem xét sử dụng các tham số được đặt tên (và chuyển một từ điển) thay vì sử dụng một bộ tuple và truyền một chuỗi. Tôi thấy việc sử dụng các đối số vị trí là một thực tế không tốt khi các vị trí không trực quan hoặc có nhiều tham số.

27

Lưu ý rằng bạn cũng có thể mở rộng một phần của danh sách đối số:

myfun(1, *("foo", "bar")) 
+11

Dường như bạn chỉ có thể thực hiện điều này nếu tuple được mở rộng sau các đối số được cung cấp thông thường - trình thông dịch không thích nó khi tôi làm điều này: 'some_func (* tuple_of_stuff, another_argument)' – Quackmatic

+3

@Quackmatic Có tuple mở rộng trong bất kỳ vị trí có vẻ hoạt động tốt trong Python 3.5.1 – River

2

Đây là phương pháp lập trình chức năng. Nó nâng tính năng mở rộng tuple ra khỏi đường cú pháp:

apply_tuple = lambda f, t: f(*t)

Ví dụ sử dụng:

from toolz import * 
from operator import add, eq 

apply_tuple = curry(apply_tuple) 

thread_last(
    [(1,2), (3,4)], 
    (map, apply_tuple(add)), 
    list, 
    (eq, [3, 7]) 
) 
# Prints 'True' 

curry redefiniton của apply_tuple tiết kiệm rất nhiều partial cuộc gọi trong thời gian dài.

+1

Điều này không hữu ích cho người mới bắt đầu. Nó sử dụng các mô-đun của bên thứ ba và làm những thứ khó hiểu khác ... – gberger

+0

gberger, 'lambda f, t: f (* t)' không sử dụng các mô-đun của bên thứ ba và tôi là người mới bắt đầu Python và điều này rất hữu ích cho tôi. Đây là một cách tiếp cận chức năng thuần túy. Nếu bạn không sử dụng kiểu này thì câu trả lời này không dành cho bạn. –

+0

toolz là bên thứ ba, là ý tôi là – gberger

0

Tôi đã gặp phải sự cố tương tự và đã tạo chức năng này mở rộng chức năng cố định. Hi vọng điêu nay co ich.

def run_argtup(func, argvalues): 
    """ 
    Execute any functions with their arguments in tuple. 

    :param func: 
    :param argvalues: 
    :return: 
    """ 
    argnames = get_func_argnames(func) 
    if len(argnames) != len(argvalues): 
     raise ValueError("Length of args doens't match.") 
    for argn, argv in zip(argnames, argvalues): 
     exec('{}=argv'.format(argn)) 
    return eval('func(%s, %s)' % argnames) 
Các vấn đề liên quan