2011-08-12 33 views
7

Trong một thời gian dài tôi đã cố gắng tìm ra cách tốt nhất để truyền cờ cho hàm python là gì. Cách đơn giản nhất là một cái gì đó như:Python: chuyển cờ sang hàm

def func(data, flag1, flag2, flag3): 
    ... 

func(my_data, True, False, True) 

Đây là thật sự tốt đẹp và súc tích, nhưng vô cùng khó đọc, vì chữ "Đúng" hay "Sai" cho bạn biết gì về những gì cờ đã được thiết lập, và bạn phải cẩn thận đếm các đối số bắt đầu từ bên trái. Bạn có thể đặt cho họ các đối số từ khóa:

def func(data, flag1=False, flag2=False, flag3=False): 
    ... 

func(my_data, flag1=True, flag3=True) 

nhưng điều này là thừa, vì "True" không mang ý nghĩa gì cả. Tôi có thể vượt qua nó như là một danh sách:

func(mydata, ['flag1', 'flag3']) 

hoặc

func(mydata, [func.flag1, func.flag3]) 

Nhưng người đầu tiên cảm thấy khá bẩn, sử dụng chuỗi như cờ, và thứ hai là vẫn còn hơi lặp đi lặp lại. Lý tưởng nhất là tôi muốn nói điều gì đó như:

func(my_data, flag1, flag3) 

để chuyển cờ sang hàm có độ dài và độ dư tối thiểu. Có cách nào để làm một cái gì đó như thế này trong python?

EDIT: tôi đã kết thúc đi với:

func(mydata, flagA=1, flagB=1) 

chủ yếu là vì những lý do nêu: thời gian biên dịch kiểm tra (so với đi qua trong chuỗi), không có ô nhiễm không gian tên (như trái ngược với việc sử dụng toàn cầu "ENUM" s) và bản mẫu tối thiểu (= 1 hoặc = 0 chỉ có 2 ký tự, so với 5 hoặc 6 cho = True hoặc = False). Nó cũng làm cho thiết lập các giá trị mặc định cho các cờ rất dễ dàng:

def func(data, flagA=1, flagB=0, flagC=1): 
    ... 

rõ ràng hơn và dễ dàng hơn nhiều so với nhảy qua các vòng để trích xuất và gán mặc định cho ** cờ kiểu kwarg. Các cờ cơ bản được kiểm tra tĩnh và rất rõ ràng/sạch sẽ để viết. Bây giờ nếu duy nhất tôi có thể cạo ra khỏi hai nhân vật cuối cùng ...

+1

Tại sao bạn muốn/cần phải vượt qua những lá cờ ở nơi đầu tiên? Có thể bạn nên suy nghĩ lại về giao diện của mình ... –

+0

Cờ sẽ được sử dụng để đặt các bool trong cấu trúc dữ liệu, sau đó sẽ kiểm soát hành vi tương lai của các hàm hoạt động trên cấu trúc dữ liệu. Đây là một cách tiếp cận hoàn toàn không phải OO, nhưng tôi đã chọn nó ra khỏi sự đơn giản; bất kể, ngay cả khi tôi đã làm nó theo phong cách OO, những thay đổi hành vi khá tinh tế và có lẽ không đáng để tạo ra cả một gia đình các lớp để xử lý. –

+0

Có lẽ bạn có thể chuyển một cấu trúc dữ liệu (đơn giản) có chứa các giá trị sau đó? Một 'bộ' cờ, hoặc cờ tên bản đồ 'dict' để bools ... –

Trả lời

3

Một số thư viện chuẩn của Python sử dụng này:

re.match(pattern, str, re.MULTILINE | re.IGNORECASE) 

Bạn có thể tinh chỉnh phương pháp này bằng cách sử dụng * args:

my.func(a, b, c, my.MULTLINE, my.IGNORECASE) 

Tôi thực sự muốn giới thiệu đi với flag1 = True:

  • có thể đọc được
  • tên cờ được chọn tại biên dịch thời gian (trừ trường hợp kwargs ** được sử dụng)
  • bạn có thể sử dụng lá cờ = 1 và flag = 0 thay vì True và False để giảm tiếng ồn
  • bạn có thể tạm thời thay đổi LONG_FLAG_NAME_YOU_DONT_REMEMBER = True False mà không cần gõ lại tên dài khi bạn sẽ cần phải thay đổi lại
3

Với args *:

def some_func(data, *args): 
    # do something 
    return args # this is just to show how it works 


>>> print some_func(12, 'test', 'test2', 'test3') 
('test', 'test2', 'test3') 

Đây là một câu hỏi tốt để hiểu làm thế nào * args và ** kwargs làm việc: *args and **kwargs?

5

bạn có thể xác định flag1 ... flagN như biến toàn cục, và xác định chức năng của bạn với func(*args)

FLAG1 = 1 
FLAG2 = 2 

def func(*args): 
    pass 

func(FLAG1, FLAG2) 

By defini ng cờ riêng biệt, thay vì sử dụng chuỗi, bạn có thể tránh lỗi chính tả trong tên cờ và một số nhức đầu khi gỡ lỗi

-1

Tôi thích các chức năng không có cờ. Thay vào đó hãy làm điều này:

def func_flag1(arg): 
    pass # something useful 

def func_flag2(arg): 
    pass # something for flag 2. 

Nhưng "flagX" thực sự sẽ có ý nghĩa như "do_X_with_option".

Tôi thích điều này vì nó làm cho nó rõ ràng hơn, bạn giữ cho các hàm đơn giản hơn (ít lỗi hơn), và bạn không phải mang một số hằng số vào các mô-đun khác (trong trường hợp cờ thực sự là một kiểu liệt kê).

+0

Vấn đề là cờ của tôi độc lập với prettymuch; do đó, những gì sẽ có O (n) cờ sẽ có O (2^n) chức năng để thi đua. Tôi có 2 lá cờ ngay bây giờ, mà sẽ mất 4 chức năng, và nó sẽ nhanh chóng có được ra khỏi tay cho ngay cả 3 hoặc 4 cờ –

3

Điều gì về việc lật qua?

flag1, flag2, flag3, flag4, flag5, flag6 = range(6) 

def func(enable=[], disable=[], 
     enabled_by_default=[flag5, flag6]): 
    enabled = set(enabled_by_default + enabled) - set(disabled) 
    if flag1 in enabled: 
     ... 
    if flag2 in enabled: 
     ... 

func(enable = [flag1, flag2, flag3], 
    disable = [flag6]) 
3

tôi đang thiếu cái tốt cũ bitwise cờ:

a = 1 
b = 2 
c = 4 
d = 8 

def func(data, flags): 
    print((flags & a) == a) 
    print((flags & b) == b) 
    print((flags & c) == c) 
    print((flags & d) == d) 

>>>> func("bla", a|c|d) 
>>>> True 
>>>> False 
>>>> True 
>>>> True 
+0

Cảm ơn bạn đã cho thấy điều này. Tôi tìm kiếm google trong nửa giờ trên "cờ bit python". – Arne

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