Methods with the same name in one class in python?
如何在一个类中声明几个具有相同名称但具有不同数量参数或不同类型的方法?
在这门课上我必须改变的是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
您可以有一个接受可变参数数目的函数。
1 2 3 4 5 6 7 8 9 | 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} |
因此,您可以按如下方式修改您的函数:
1 2 3 4 5 6 7 | 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 |
不能。没有重载、多方法或类似的东西。一个名字指的是一件事。就语言而言,你总是可以自己模仿它们…您可以使用
简短回答:你不能(见前面的讨论)。通常您会使用类似的方法(您可以添加更多类型检查和重新排序):
1 2 3 4 5 6 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 |
您可以在python中尝试多种方法:
http://www.artima.com/weblogs/viewpost.jsp?线程=101605
但我不认为多方法是一种可行的方法。相反,传递给方法的对象应该具有公共接口。您正在尝试实现类似于C++中的方法重载,但在Python中很少需要这种方法。一种方法是使用
我认为所有答案中都缺少一个非常简单的例子,那就是:当方法变化之间的唯一区别是参数的数量时,该怎么做。答案仍然是使用参数数目可变的方法。
例如,您从一个需要使用两个参数的方法开始
1 2 | def method(int_a, str_b): print("Got arguments: '{0}' and '{1}'".format(int_a, str_b) |
然后您需要添加一个变量,只使用第二个参数(例如,因为整数是多余的),解决方案非常简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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") |
这个解决方案的好处在于,无论调用代码以前使用过关键字参数还是位置参数,它都将继续工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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 |
您可能需要类似以下的模式:请注意,在方法名称的开头添加"u"是标记私有方法的约定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 |
Python与Java无关。
没有真正的类型,只有带有方法的对象。
有一种方法可以测试通过的对象是否来自某个类,但这主要是坏的实践。
但是,要为前两个方法生成的代码应该类似于
1 2 3 4 | class MyClass(object): def my_method(self, str1, str2=None): print str1 if str2: print str2 |
第三个,嗯…使用其他名称…