Python 中一个类中具有相同名称的方法

问题描述 投票:0回答:12

如何在一个类中声明几个同名但参数数量或类型不同的方法?

下节课我必须改变什么?

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
python overloading
12个回答
89
投票

您可以拥有一个接受可变数量参数的函数。

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

32
投票

你不能。没有重载或多重方法或类似的东西。一个名字指的是一件事。无论如何,就语言而言,您始终可以自己模拟它们...您可以使用 isinstance 检查类型(但请正确执行 - 例如,在 Python 2 中,使用

basestring
来检测字符串和 unicode ),但它很丑陋,通常不鼓励并且很少有用。如果这些方法执行不同的操作,请为它们指定不同的名称。还要考虑多态性。
    


23
投票
@typing.overload

为重载函数/方法提供类型注释。

来自文档

@overload def process(response: None) -> None: ... @overload def process(response: int) -> tuple[int, str]: ... @overload def process(response: bytes) -> str: ... def process(response): <actual implementation>



7
投票
请参阅之前的讨论

)。通常您会使用类似的东西(您可以添加更多类型检查和重新排序): 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



2
投票
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



2
投票

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

但我不认为多种方法是可行的方法。相反,传递给方法的对象应该具有公共接口。您正在尝试实现类似于 C++ 中的方法重载,但在 Python 中很少需要。实现此目的的一种方法是使用

ifs

进行级联

isinstance
,但这很丑陋。
    


2
投票

没有真正的类型,只有带有方法的对象。

有一种方法可以测试传递的对象是否来自类,但这主要是不好的做法。

但是,您想要为前两个方法生成的代码应该类似于

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

对于第三个,嗯...使用不同的名称...


2
投票
结构模式匹配

def my_method(parameters): match parameters: case str(): # Case 1 case (str(), str()): # Case 2 case (str(), int()): # Case 3 case _: print('no match')



0
投票

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



0
投票


0
投票

假设您从一个需要使用两个参数的方法开始

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")

这个解决方案的好处是,无论调用代码之前使用了关键字参数还是位置参数,它仍然可以继续工作。


0
投票
@overload

解决了这个问题:VS Code -> f12 on

open()
-> 它显示了一堆
open()
函数的重复项:
@overload
def open(...):
@overload
def open(...):
...

所以,这就是结果...

class MyClass: """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" @overload def my_method(self,parameter_A_that_Must_Be_String): print parameter_A_that_Must_Be_String @overload 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 @overload 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

抱歉让你紧张了......

© www.soinside.com 2019 - 2024. All rights reserved.