Methods with the same name in one class in Python

前端 未结 9 1626
执笔经年
执笔经年 2021-01-30 02:18

How can I declare a few methods with the same name, but with different numbers of parameters or different types in one class?

What must I change in the following class?

相关标签:
9条回答
  • 2021-01-30 02:43

    This cannot work. No matter how many arguments you have, the name m will be overriden with the second m method.

    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
    

    The output will simple be:

    m second 1
    
    0 讨论(0)
  • 2021-01-30 02:46

    Python is nothing like Java.

    There are not really types, just objects with methods.

    There is a way to test if a passed object is from a class, but it is mainly bad practices.

    However, the code you want to produce for the two first methods should be something like

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

    For the third, well... Use a different name...

    0 讨论(0)
  • 2021-01-30 02:47

    You can try multimethods in Python:

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

    But I don't believe multimethod is a way to go. Rather objects that you pass to a method should have common interface. You are trying to achieve method overloading similar to the one in C++, but it is very rarely required in Python. One way to do this is a cascade of ifs using isinstance, but that's ugly.

    0 讨论(0)
  • 2021-01-30 02:48
    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
    
    0 讨论(0)
  • 2021-01-30 02:49

    You probably want a pattern similar to the following: Note that adding '_' to the beginning of a method name is convention for marking a private method.

    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)
  • 2021-01-30 02:53

    I think one very simple example is missing from all the answers, and that is: what to do when the only difference between variations on the method is the number of arguments. The answer still is to use a method with variable number of arguments.

    Say, you start with a method that requires use of two arguments

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

    then you need to add a variant with just the second argument (say, because the integer is redundant), the solution is very simple:

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

    The nice thing about this solution is that no matter if the calling code used keyword arguments or positional arguments before, it will still continue to work.

    0 讨论(0)
提交回复
热议问题