Является ли это питонным, чтобы имитировать перегрузку методов, как в статически типизированных языках? Под этим я подразумеваю написание функции, которая проверяет типы своих аргументов и ведет себя по-разному в зависимости от этих типов.

Вот пример:

class EmployeeCollection(object):
    @staticmethod
    def find(value):
        if isinstance(value, str):
            #find employee by name and return
        elif isinstance(value, int):
            #find employee by employee number and return
        else:
            raise TypeError()
8
hwiechers 4 Сен 2010 в 18:51

5 ответов

Лучший ответ

Не очень Pythonic, кроме , возможно, в версии 2.6 или лучше, если все проверки основаны на новых абстрактных базовых классах, которые частично предназначены именно для облегчения такого использования. Если вам когда-нибудь понадобится проверка типов для классов бетона , то вы знаете , что делаете свой код хрупким и ограничивает его использование.

Так, например, проверьте, есть ли у вас экземпляр numbers.Integral не так уж и плохо - что новая ABC существует в значительной степени именно для того, чтобы облегчить такую проверку. Проверка наличия у вас экземпляра int - это катастрофа, исключение long, gmpy.mpz и целого ряда других целочисленных чисел, что абсолютно бесполезно: никогда не проверяйте конкретные занятия!

Строки - сложный случай, но basestring абстрактный класс (не один из новых видов азбуки) это возможность. Возможно, это слишком ограничительно, но если вы используете другие азбуки вокруг него, это может отчасти сработать, если вам действительно нужно. Определенно, нет str - зачем вообще исключать unicode ?!

13
Alex Martelli 4 Сен 2010 в 15:15

Не совсем, так как вы теряете возможность использовать типы, которые не совсем, но достаточно близки. Вместо этого создайте два отдельных метода (find_by_name() и find_by_number()).

13
Ignacio Vazquez-Abrams 4 Сен 2010 в 14:55

Нет, проверка типов здесь не Pythonic. Другой вариант, если вам не нравятся несколько методов, это придерживаться одного метода, но использовать несколько параметров:

def find(name=None, employee_number=None):
    if sum(x != None for x in (name, employee_number)) != 1:
        #raise exception - exactly one value should be passed in
    if name is not None:
        #find employee by name and return
    if employee_number is not None:
        #find employee by employee number and return

При использовании намерение так же очевидно, как и с несколькими методами:

employee1 = x.find(name="John Smith")
employee2 = x.find(employee_number=90210)
5
Scott Griffiths 5 Сен 2010 в 14:54

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

Вот два способа сделать это:

class EmployeeCollection(object):
    def find(value):
        try:
            #find employee by name and return
        catch:
            try:
                #find employee by employee number and return
            catch:
                raise TypeError()

Но это вроде противно. вот как я обычно делаю это:

class EmployeeCollection(object):
    def find(value):
        if hasattr(value, 'join'):
            #find employee by name and return
        elif hasattr(value, '__div__'):
            #find employee by employee number and return
        else:
            raise TypeError()

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

1
SingleNegationElimination 5 Сен 2010 в 07:26

Я бы сказал, что да, это «Pythonic», и есть примеры, подтверждающие это (что не предоставлено другими авторами). Чтобы ответить на этот вопрос правильно, должны быть примеры!

Из ядра Python:

  • string.startswith() Он принимает либо строку, либо кортеж (из строк).
  • string.endswith()

В пимонго:

  • find_one() принимает либо объект dict для поиска, либо он использует другой другой объект в качестве идентификатора.

Извините, я не знаю больше, но я думаю, что есть МНОГИЕ примеры методов, которые ведут себя по-разному в соответствии с заданными параметрами. Это часть красоты неиспользуемых типов.

2
Scott Griffiths 5 Сен 2010 в 06:31