2010-08-14 44 views
6

Tôi đã nhìn chằm chằm vào một đoạn mã Python mà tôi đã tạo ra, mặc dù chính xác, là xấu. Có cách nào khác để làm điều này không?Cách thức lặp lại một cách gọi phương thức trên các đối số hữu hạn khác nhau

r = self.get_pixel(x,y, RED) 
    g = self.get_pixel(x,y, GREEN) 
    b = self.get_pixel(x,y, BLUE) 
    t = function(r,g,b) 
    if t: 
     r2, g2, b2 = t 
     self.set_pixel(x,y,RED, r2) 
     self.set_pixel(x,y,GREEN, g2) 
     self.set_pixel(x,y,BLUE, b2) 

Vấn đề là sự lặp lại của phương pháp này đòi hỏi phải get_pixelset_pixel. Để biết thông tin của bạn:

RED, GREEN, BLUE = range(3) 

Cũng lưu ý rằng tôi muốn giữ nguyên độ rõ nét và độ sạch của mã.

Trả lời

1

Để gọi một hàm với đối số khác nhau và thu thập các kết quả mà bạn có thể sử dụng một danh sách hiểu:

r1, r2, r3 = [foo(x) for x in [x1, x2, x3]] 

Để gọi một chức năng cho nó tác dụng phụ tôi khuyên bạn nên không sử dụng một danh sách hiểu biết và thay vì sử dụng một bình thường cho vòng lặp:

ijs = [(i1, j1), (i2, j2), (i3, j3)] 
for i, j in ijs: 
    bar(i, j) 

Tuy nhiên vấn đề của bạn thực sự không phải là bạn không nên kêu gọi thiết lập điểm ảnh của bạn cho mỗi màu riêng. Nếu có thể, thay đổi API của bạn để bạn có thể làm điều này theo đề nghị của John Machin:

old_colors = self.get_pixel_colors(x, y) 
new_colors = function(*old_colors) 
if new_colors: 
    self.set_pixel_colors(x, y, *new_colors) 
+3

-1 này được chỉ thêm cách giải quyết xấu xí đến một API xấu xí. Đó là thời gian thiết kế lại API - xem câu trả lời của @Muhammad Alkarouri, hoặc của tôi. –

+0

@John Machin: Xin lỗi tôi đã đề cập đến điều đó. Kế hoạch của tôi trước tiên là đưa ra một câu trả lời cụ thể cho câu hỏi chính xác và sau đó xử lý bức tranh lớn hơn và giải thích các phương pháp thay thế. Nhưng trong khi tôi đang gõ phần đầu tiên, những người khác đã đánh tôi đến phần thứ hai.Tôi không chỉ muốn sao chép chính xác cùng một thông tin mà những người khác đã đăng trong bài đăng của tôi vì vậy tôi chỉ để lại nó vì nó không có ai trả lời câu hỏi. Bây giờ tôi thấy câu trả lời của tôi đã được chấp nhận và tôi không thể xóa câu trả lời của mình. Vì vậy, tôi đã đưa câu trả lời của bạn vào bài đăng của tôi. Ổn chứ? Hoặc bạn đề nghị tôi nên làm gì? –

+0

Tôi sẽ nói theo mẫu phiếu bầu mà giới thiệu của bạn cho câu trả lời khác là làm việc hay không cần thiết, vì vậy tôi không nghĩ bạn nên lo lắng về nó ngay bây giờ. Và cảm ơn vì đã đề cập đến tôi là "những người khác đánh tôi" :) –

1
colors = (RED, GREEN, BLUE) 

r, g, b = [self.get_pixel(x, y, col) for col in colors] 
t = function(r, g, b) 
for col, rgb in zip(colors, t): 
    self.set_pixel(x, y, col, rgb) 
4

Tôi sẽ sử dụng một tuple tên để biểu thị màu, và thay đổi lớp để sử dụng màu sắc các thuộc tính thay vì cá nhân get_pixel(x,y,c). Ví dụ:

from collections import namedtuple 
Color = namedtuple('Color', 'red green blue') 
#... 

color = self.get_pixel(x, y) 
t = function(*color) 
if t: 
    self.set_pixel(x, y, color) 

Sửa: nhờ John Machin cho chỉnh được đề xuất ở đây. Câu trả lời của ông cũng cung cấp cho cái nhìn sâu sắc hơn vào những lý do cho cách tiếp cận này. Tôi sẽ thêm rằng namedtuple mang lại lợi thế là có các trường như color.red, color.green, color.blue mà tôi muốn có sẵn. YMMV.

+0

Điều này yêu cầu hoặc thay đổi args của 'function' (có thể không được 'sở hữu' bởi OP), hoặc viết' t = function (* color) '. –

+0

@John Machin: khá đúng. Tôi quên '*', đó là lý do tôi đã sử dụng một tuple ngay từ đầu. Tôi vừa chỉnh sửa câu trả lời để sửa nó. –

+0

và dòng cuối cùng phải là 'self.set_pixel (x, y, màu)' –

5

Khi bạn đang sử dụng self, có vẻ như get_pixel vv là các phương thức của lớp học của bạn. Thay vì hiểu danh sách và zip() và cách giải quyết khác, hãy xem API và sửa chúng. Hai đề xuất:

  1. Viết phương thức khác get_pixel_colors(x, y) trả về 3 bộ. Sau đó, bạn có thể viết r, g, b = self.get_pixel_colors(x, y)
  2. Tương tự: self.set_pixel_colors(x, y, r, g, b)

Thậm chí tốt hơn, bạn có thể sử dụng các ký hiệu *args:

old_colors = self.get_pixel_colors(x, y) 
new_colors = function(*old_colors) 
if new_colors: 
    self.set_pixel_colors(x, y, *new_colors) 
Các vấn đề liên quan