Pythonic способ повторения вызова метода на разных конечных аргументах - PullRequest
6 голосов
/ 15 августа 2010

Я смотрел на кусок кода Python, который я произвел, что, хотя и правильно, уродливо. Есть ли более питонический способ сделать это?

    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)

Проблема заключается в повторении вызовов методов для get_pixel и set_pixel. Для вашей информации:

    RED, GREEN, BLUE = range(3)

Также обратите внимание, что я хотел бы сохранить ясность и чистоту кода.

Ответы [ 4 ]

5 голосов
/ 15 августа 2010

Поскольку вы используете self, кажется, что get_pixel и т. Д. Являются методами вашего класса.Вместо списочного понимания и zip() и других обходных путей, посмотрите на API и исправьте их.Два предложения:

  1. Напишите другой метод get_pixel_colors(x, y), который возвращает 3-кортеж.Тогда вы можете написать r, g, b = self.get_pixel_colors(x, y)
  2. Аналогично: self.set_pixel_colors(x, y, r, g, b)

Еще лучше, вы можете использовать запись *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)
4 голосов
/ 15 августа 2010

Я бы использовал именованный кортеж для представления цвета и изменил бы класс, чтобы использовать атрибуты цвета, а не отдельные get_pixel(x,y,c).Например:

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)

Редактировать : спасибо John Machin за исправления, предложенные здесь.Его ответ также дает более глубокое понимание причин такого подхода.Я бы добавил, что namedtuple дает преимущество наличия таких полей, как color.red, color.green, color.blue, которые я хотел бы иметь в наличии.YMMV.

1 голос
/ 15 августа 2010
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)
1 голос
/ 15 августа 2010

Чтобы вызвать функцию с разными аргументами и собрать результаты, вы можете использовать понимание списка:

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

Чтобы вызвать функцию для ее побочных эффектов Я бы рекомендовал не использовать понимание списка, а вместо этого использовать обычный цикл for:

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

Однако ваша проблема на самом деле не в том, что вы не должны называть свой установленный пиксель для каждого цвета отдельно . Если это вообще возможно, измените свой API, чтобы вы могли сделать это, как предложено 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...