2016-02-01 2 views
0

Согласно Clean Code, функция должна принимать нулевые аргументы, когда это возможно.Вызов функций/методов Python с нулевыми аргументами

Если мы возьмем тривиальный пример в Python с функцией, которая не делает ничего больше, чем добавить 2 к тому, что ей передается:

def add_two(x): 
    return x + 2 

>add_two(1) 
3 

Единственный способ, которым я могу видеть, что такая функция может иметь ноль аргументов передается в него: включение в класс:

class Number(object): 
    def __init__(self, x): 
     self.x = x 

    def add_two(self): 
     return self.x + 2 

>n = Number(1) 
>n.add_two() 
3 

Это вряд ли стоит усилий. Есть ли другой способ достижения функции без аргументов в этом примере?

+3

0 Я думаю, что кто сказал, что это означает, что у вас не должно быть функций с 20 аргументами. Конечно, в вашем случае вполне разумно иметь один аргумент. – nbro

+0

просто для echo @nbro, в этом случае логично предположить, что ваша функция будет иметь один аргумент. Это не делает код менее чистым. Если вы хотите сделать эту функцию меньше аргументом, вы всегда можете запросить аргумент. Если вызывающий абонент вводит номер, чтобы добавить два из них, предложив ему функцию (если прецедент допускает такие возможности) – Amit

+2

ваш метод по-прежнему принимал аргумент 'self' ... – Fabricator

ответ

2

Почему бы вам не использовать аргумент метода по умолчанию

def add_two(x=0): 
    return x + 2 
>>> add_two(1) 
3 
>>> add_two() 
2 
>>> 
3

Если мы возьмем тривиальный пример в Python с функцией, которая не делает ничего больше, чем прибавить 2 к тому, что ей передается: . .. Есть ли другой способ достижения функции без аргументов в этом примере ?

Одним словом, нет. В нескольких словах: по определению ваша функция принимает аргумент. Невозможно принять аргумент, не принимая аргумента.

+2

Единственный способ сделать что-то, что _passed_ для функции, - заставить функцию принять аргумент. –

+0

@ TadhgMcDonald-Jensen Да, я бы принял это как эквивалентное и более точное утверждение. –

+1

Технически вы можете делать только «глобалы», но это может быть худшая практика и полностью побеждает цель использования функций. (Было бы любопытно, чтобы увидеть все приложение написано, что ужасно, хотя если вам не нужно его поддерживать). –

3

В общем

Это действительно плохо общий совет, никакие методов аргумента не велики для объектов, которые изменяют объект таким образом, что не требует не внешних данных или для функций, которые только взаимодействуют с глобал (вы действительно должны иметь минимальную потребность в этом). В вашем случае вам необходимо изменить данный объект с помощью внешних данных, и оба объекта являются встроенным (int).

В этом случае просто используйте функцию с двумя аргументами.

Слишком много аргументов

Теперь, вот где совет получает хорошие. Скажем, мне нужно выполнить сложную задачу с многочисленными аргументами.

def complicatedfunction(arg1, arg2, arg3, arg4, arg5, arg6): 
    '''This requires 6 pieces of info''' 

    return ((arg1 + arg2)/(arg3 * arg4)) ** (arg5 + arg6) 

В этом случае, вы делаете код нечитаемым, и вы должны уменьшить количество аргументов 5 или менее.

Снижение Аргумент Считает

В этом случае, вы могли бы пройти namedtuple:

from collections import namedtuple 
Numbers = namedtuple("Numbers", "numerator denominator exponent") 
mynumber = Numbers(1+2, 3+4, 5+6) 

def complicatedfunction(number): 
    return (number.numerator/number.denominator) ** (number.exponent) 

Это имеет дополнительное преимущество, а затем сделать ваш код легко изменить в будущем. Скажем, мне нужно добавить еще один аргумент: я могу просто добавить это как значение в namedtuple.

from collections import namedtuple 
Numbers = namedtuple("Numbers", "numerator denominator exponent add") 
mynumber = Numbers(1+2, 3+4, 5+6, 2) 

def complicatedfunction(number): 
    value = (number.numerator/number.denominator) ** (number.exponent) 
    return value + number.add 

объектно-ориентированное проектирование

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

from collections import namedtuple 


class Numbers(namedtuple("Numbers", "numerator denominator exponent add")): 

    def process(self): 
     value = (self.numerator/self.denominator) ** (self.exponent) 
     return value + self.add 

mynumber = Numbers(1+2, 3+4, 5+6, 2) 
Смежные вопросы