Подтвердить что ты не робот

Методы с тем же именем в одном классе в python?

Как объявить несколько методов с тем же именем, но с различным количеством параметров или разных типов в одном классе?

Что мне нужно изменить в этом классе:

class MyClass:
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
    def my_method(self,parameter_A_that_Must_Be_String):
        print parameter_A_that_Must_Be_String

    def my_method(self,parameter_A_that_Must_Be_String,parameter_B_that_Must_Be_String):
        print parameter_A_that_Must_Be_String
        print parameter_B_that_Must_Be_String

    def my_method(self,parameter_A_that_Must_Be_String,parameter_A_that_Must_Be_Int):
        print parameter_A_that_Must_Be_String * parameter_A_that_Must_Be_Int
4b9b3361

Ответ 1

У вас может быть функция, которая принимает переменное количество аргументов.

def my_method(*args, **kwds):
    # do something

# when you call the method
my_method(a1, a2, k1=a3, k2=a4)

# you get: 
args = (a1, a2)
kwds = {'k1':a3, 'k2':a4}

Итак, вы можете изменить свою функцию следующим образом:

def my_method(*args):
    if len(args) == 1 and isinstance(args[0], str):
        # case 1
    elif len(args) == 2 and isinstance(args[1], int):
        # case 2 
    elif len(args) == 2 and isinstance(args[1], str):
        # case 3

Ответ 2

Вы не можете. Не существует перегрузок или мультиметодов или подобных вещей. Одно имя относится к одной вещи. Что касается языка в любом случае, вы всегда можете имитировать их самостоятельно... Вы можете проверять типы с помощью isinstance (но, пожалуйста, сделайте это правильно - например, в Python 2, используйте basestring для обнаружения как строк, так и unicode), но он уродливый, обычно обескураженный и редко полезный. Если методы делают разные вещи, дайте им разные имена. Рассмотрим также полиморфизм.

Ответ 3

Короткий ответ: вы не можете (посмотреть предыдущее обсуждение). Как правило, вы должны использовать что-то вроде (вы можете добавить больше проверки типов и изменить порядок):

def my_method(self,parameter_A, parameter_B=None):
  if isinstance(parameter_B, int):
    print parameter_A * parameter_B
  else:
    print parameter_A
    if parameter_B is not None:
      print parameter_B

Ответ 4

Вы можете попробовать мультиметоды в Python:

http://www.artima.com/weblogs/viewpost.jsp?thread=101605

Но я не считаю, что мультиметод - это путь. Скорее объекты, которые вы передаете методу, должны иметь общий интерфейс. Вы пытаетесь добиться перегрузки метода, аналогичной той, что и на С++, но это очень редко требуется в python. Один из способов сделать это - каскад ifs с помощью isinstance, но этот уродливый.

Ответ 5

Python не похож на Java.

На самом деле нет типов, просто объектов с методами.

Есть способ проверить, прошел ли переданный объект из класса, но в основном это неправильная практика.

Однако код, который вы хотите создать для двух первых методов, должен быть чем-то вроде

class MyClass(object):
    def my_method(self, str1, str2=None):
        print str1
        if str2: print str2

Для третьего, ну... Используйте другое имя...

Ответ 6

Вероятно, вам нужен шаблон, похожий на следующий: Обратите внимание, что добавление '_' в начало имени метода является условным обозначением частного метода.

class MyClass:
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
    def my_method(self,parameter_A_that_Must_Be_String, param2=None):
        if type(param2) == str:
            return self._my_method_extra_string_version(parameter_A_that_Must_Be_String, param2)
        elif type(param2) == int:
            return self._my_method_extra_int_version(parameter_A_that_Must_Be_String, param2)
        else:
            pass # use the default behavior in this function
        print parameter_A_that_Must_Be_String

    def _my_method_extra_string_version(self,parameter_A_that_Must_Be_String, parameter_B_that_Must_Be_String):
        print parameter_A_that_Must_Be_String
        print parameter_B_that_Must_Be_String

    def _my_method_extra_int_version(self,parameter_A_that_Must_Be_String, parameter_A_that_Must_Be_Int):
        print parameter_A_that_Must_Be_String * parameter_A_that_Must_Be_Int

Ответ 7

class MyClass:
    def __init__(this, foo_str, bar_int):
        this.__foo = foo_str
        this.__bar = bar_int

    def foo(this, new=None):
        if new != None:
            try:
                this.__foo = str(new)
            except ValueError:
                print("Illegal value. foo unchanged.")

        return this.__foo

    def bar(this, new=None):
        if new != None:
            try:
                this.__bar = int(new)
            except ValueError:
                print("Illegal value. bar unchanged.")

        return this.__bar

obj = MyClass("test", 42)
print(obj.foo(), obj.bar())

print(obj.foo("tset"), obj.bar(24))

print(obj.foo(42), obj.bar("test"))

Output:
    test 42
    tset 24
    Illegal value. bar unchanged.
    42 24

Ответ 8

Я думаю, что один очень простой пример отсутствует во всех ответах, а именно: что делать, когда единственная разница между вариациями метода - это количество аргументов. Ответ по-прежнему заключается в использовании метода с переменным числом аргументов.

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

def method(int_a, str_b):
    print("Got arguments: '{0}' and '{1}'".format(int_a, str_b)

тогда вам нужно добавить вариант только с помощью второго аргумента (скажем, потому что целое является избыточным), решение очень просто:

def _method_2_param(int_a, str_b):
    print("Got arguments: '{0}' and '{1}'".format(int_a, str_b))

def _method_1_param(str_b):
    print("Got argument: '{0}'".format(str_b))

def method(*args, **kwargs):
    if len(args) + len(kwargs) == 2:
        return _method_2_param(args, kwargs)
    elif len(args) + len(kwargs) == 1:
        return _method_1_param(args, kwargs)
    else:
        raise TypeError("Method requires one or two arguments")

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

Ответ 9

Это не может работать. Независимо от того, сколько аргументов у вас есть, имя m будет переопределено вторым методом m.

class C:
    def m(self):
        print('m first')
    def m(self, x):
        print(f'm second {x}')


ci=C();
#ci.m() # will not work TypeError: m() missing 1 required positional argument: 'x'
ci.m(1) # works

Результат будет простым:

m second 1