Python:“TypeError: __init__()完全接受“x”参数(“y”给定);x > 0

时间:2021-02-25 23:18:19

The type error happened to me when assuming one language's concepts, specifically C++/Java/etc.'s "Function Overloading" [1] of parameters, works in another, Python in this case. My conclusion likely needs review, and could be more detailed with someone that knows Python's source code, but I believe it is generally a good assessment and advice.

当假设一种语言的概念,特别是c++ /Java/等时,我就遇到了类型错误。的“函数重载”[1]参数,在另一个例子中是Python。我的结论可能需要审查,并且可以与了解Python源代码的人进行更详细的讨论,但我认为这通常是一个很好的评估和建议。

Experiment

Code 1:

代码1:

class Toolbox:    
  trayA = ()    
  trayB = ()    

  def __init__(self):
        self.trayA = ("nail", "screw")        
        self.trayB = ("hammer", "nail", "long nail")

  def __init__(self,tA,tB):
        self.trayA = tA
        self.trayB = tB

#Instance defs
tb = Toolbox()
#tb = Toolbox(("n1","n2","n5"),("screwdriver","long screw"))

#Test
print(tb.trayA)
print(tb.trayB)

Result:
"TypeError: init() takes exactly 3 arguments (1 given)" Analysis:
*The number of parameters expected, 3, matches the second init definition of the 2 defined.
*The definition used was the second of the 2 defined.

结果:“TypeError: init()只接受3个参数(给定1个)”分析:*预期参数的数量,3,与定义的2的第二个init定义相匹配。*所使用的定义是所定义的两个定义中的第二个。

Code 2:
Description:
From Code 1, removed the comment on the 3-param call.
Commented out the 1-param call.
Result:
pass (i.e. no error)

代码2:描述:从代码1中删除对3-param调用的注释。注释掉了1-param调用。结果:通过(即没有错误)

Code 3:
Description:
From Code 1, switched order of init definitions.
Result:
pass

代码3:描述:从代码1开始,转换初始化定义的顺序。结果:通过

Code 4:
Description:
From Code 3, commented out the 1-param call, and uncommented the 3-param call
Result:
Fail "TypeError: init() takes exactly 1 argument (3 given)"

代码4:Description:从代码3中,注释掉1-param调用,未注释掉3-param调用结果:Fail“TypeError: init()只接受一个参数(3)”

Conclusion:


The last defined function/method of a sequence of overloaded functions/methods, is the only definition Python refers to when a programmer is defining/calling an instance of those functions/methods.

Acknowledgement

I believe it is important to be specific when the audience is a technical one, the author is knowledgeable enough, and there is enough time to consider the conditions for specifics (if not strong enough in a concept to immediately use the term). Thank you Paul Rooney for helping me be more specific, using "Function Overloading"[1] in place of "Polymorphism"[2,3], especially after I use the term, "specifically".

我认为,当读者是一个技术性的人,作者有足够的知识,有足够的时间考虑细节的条件(如果在概念上不够强,不能立即使用术语)时,一定要有针对性。感谢Paul Rooney帮助我更加具体,使用“函数重载”[1]代替“多态性”[2,3],尤其是在我使用“具体”这个词之后。

Reference

[1]: "Function overloading". Wikipedia. https://en.wikipedia.org/wiki/Function_overloading. Accessed 9/20/2017.
[2]: Cohoon & Davidson. C++ Program Design. 3rd ed. 2002.
[3]: "Polymorphism (computer science)". Wikipedia. en.wikipedia.org/wiki/Polymorphism_(computer_science). Accessed 9/20/2017.

[1]:“函数重载”。*。https://en.wikipedia.org/wiki/Function_overloading。9/20/2017访问。[2]:Cohoon &戴维森。c++程序设计。第三版。2002。[3]:“多态性(计算机科学)”。*。en.wikipedia.org/wiki/Polymorphism_(computer_science)。9/20/2017访问。

2 个解决方案

#1


0  

Thank you all for your tips. Based on the advice provided earlier by John Gordon and AndMar to use *argv, I revised the code to handle multiple parameter inputs.

谢谢大家的建议。根据John Gordon和AndMar早前提供的使用*argv的建议,我修改了代码以处理多个参数输入。

class Toolbox:
trayA = ()
trayB = ()
def __init__(self,*argv):
    if len(argv) == 2:
        self.trayA = argv[0]
        self.trayB = argv[1]
    else:
        self.trayA = ("nail", "screw")
        self.trayB = ("hammer", "nail", "long nail")
def printContents(self,a):
    print("Init Arguments Count Used = ",a)
    print(self.trayA)
    print(self.trayB)
    print("")


#Initialize and Print
tb = Toolbox()
tb.printContents(0)

tb = Toolbox(("n1","n2","n5"),("screwdriver","long screw"))
tb.printContents(2)

tb = Toolbox(("n1","n2","n5"),("screwdriver","long screw"),("n3","n7","drill bit"))
tb.printContents(3)

Result

('Init Arguments Count Used = ', 0)
('nail', 'screw')
('hammer', 'nail', 'long nail')

('Init Arguments Count Used = ', 2)
('n1', 'n2', 'n5')
('screwdriver', 'long screw')

('Init Arguments Count Used = ', 3)
('nail', 'screw')
('hammer', 'nail', 'long nail')

#2


0  

if there are more than one function with the same name, python use the last one. pythonic way to make different constructors is like:

如果有多个函数具有相同的名称,那么python使用最后一个函数。用毕达哥拉斯的方法构造不同的构造函数是这样的:

class Toolbox:
    def __init__(self, tA=None, tB=None):
        if not tA:
            tA = ("nail", "screw")

        if not tB:
            tB = ("hammer", "nail", "long nail")

        self.trayA = tA
        self.trayB = tB

    def __str__(self):
        return "trayA=%s, trayB=%s" % (self.trayA, self.trayB)


a = Toolbox()
b = Toolbox(('bolt', 'nut'))
c = Toolbox(('bolt', 'nut'), ('saw', 'chisel'))


print(a)
print(b)
print(c)

output

输出

trayA=('nail', 'screw'), trayB=('hammer', 'nail', 'long nail')
trayA=('bolt', 'nut'), trayB=('hammer', 'nail', 'long nail')
trayA=('bolt', 'nut'), trayB=('saw', 'chisel')

python use this method for python type() too. u can check the type of a variable:

python对python类型()也使用这种方法。你可以检查变量的类型:

>>> x="str"
>>> type(x)
<class 'str'>

or u can make a class with it.

或者你可以用它来上课。

class A:
    pass
x = A()
print(type(x))

is equal with :

等于:

A = type("A", (), {})
x = A()
print(type(x))

#1


0  

Thank you all for your tips. Based on the advice provided earlier by John Gordon and AndMar to use *argv, I revised the code to handle multiple parameter inputs.

谢谢大家的建议。根据John Gordon和AndMar早前提供的使用*argv的建议,我修改了代码以处理多个参数输入。

class Toolbox:
trayA = ()
trayB = ()
def __init__(self,*argv):
    if len(argv) == 2:
        self.trayA = argv[0]
        self.trayB = argv[1]
    else:
        self.trayA = ("nail", "screw")
        self.trayB = ("hammer", "nail", "long nail")
def printContents(self,a):
    print("Init Arguments Count Used = ",a)
    print(self.trayA)
    print(self.trayB)
    print("")


#Initialize and Print
tb = Toolbox()
tb.printContents(0)

tb = Toolbox(("n1","n2","n5"),("screwdriver","long screw"))
tb.printContents(2)

tb = Toolbox(("n1","n2","n5"),("screwdriver","long screw"),("n3","n7","drill bit"))
tb.printContents(3)

Result

('Init Arguments Count Used = ', 0)
('nail', 'screw')
('hammer', 'nail', 'long nail')

('Init Arguments Count Used = ', 2)
('n1', 'n2', 'n5')
('screwdriver', 'long screw')

('Init Arguments Count Used = ', 3)
('nail', 'screw')
('hammer', 'nail', 'long nail')

#2


0  

if there are more than one function with the same name, python use the last one. pythonic way to make different constructors is like:

如果有多个函数具有相同的名称,那么python使用最后一个函数。用毕达哥拉斯的方法构造不同的构造函数是这样的:

class Toolbox:
    def __init__(self, tA=None, tB=None):
        if not tA:
            tA = ("nail", "screw")

        if not tB:
            tB = ("hammer", "nail", "long nail")

        self.trayA = tA
        self.trayB = tB

    def __str__(self):
        return "trayA=%s, trayB=%s" % (self.trayA, self.trayB)


a = Toolbox()
b = Toolbox(('bolt', 'nut'))
c = Toolbox(('bolt', 'nut'), ('saw', 'chisel'))


print(a)
print(b)
print(c)

output

输出

trayA=('nail', 'screw'), trayB=('hammer', 'nail', 'long nail')
trayA=('bolt', 'nut'), trayB=('hammer', 'nail', 'long nail')
trayA=('bolt', 'nut'), trayB=('saw', 'chisel')

python use this method for python type() too. u can check the type of a variable:

python对python类型()也使用这种方法。你可以检查变量的类型:

>>> x="str"
>>> type(x)
<class 'str'>

or u can make a class with it.

或者你可以用它来上课。

class A:
    pass
x = A()
print(type(x))

is equal with :

等于:

A = type("A", (), {})
x = A()
print(type(x))