我看到了这段特殊的代码:
def g(x,y):
return x+y
def g(x,y):
return x*y
x,y=6,7
print (g(x,y))
显然(但不是我)的输出是42.有人可以解释一下这种行为吗?这是我想的方法,但我还没有得到这个流程。
答案 0 :(得分:3)
定义一个函数并重新定义它时,它将使用你定义的最后一个函数,即使参数不同:
def g(x,y):
return x+y
def g(x,y):
return x*y
x,y=6,7
print (g(x,y))
def hello():
return 'hello'
def hello():
return 'bye'
print hello()
def withone(word):
return word
def withone():
return 1==1
print withone('ok')
输出:
42
bye
TypeError: withone() takes no arguments (1 given)
Python中的函数名称更像是简单的变量:
def hello():
return 'hello'
iamhello = hello # bind to the old one
def hello():
return 'bye'
print hello() # here is the new guy
print iamhello()
输出:
bye
hello
答案 1 :(得分:2)
魔鬼是函数定义的顺序。
这在技术上不是方法覆盖,因为它需要类继承,而是python声明和引用函数的结果。
当声明一个函数时,python在一个以函数定义命名的变量中存储对该函数的引用。 (例如变量将是" foo"对于" def foo():")
通过两次声明该函数,该变量的值将被第二个定义覆盖。
答案 2 :(得分:1)
从上到下解析Python脚本。 因此,无论何时出现变量或函数或类的相同名称,它都会覆盖之前与此名称关联的任何定义。
def g(x,z):
print('first')
def g():
print('second')
g = 3
print g
print g()
请看这个例子,它会导致'3'的打印输出,然后是异常:'TypeError: 'int' object is not callable'
名称g首先是一个带有两个参数的函数,然后它被重新定义为一个没有参数的函数,然后它被重新定义为一个int。 这显然不能被称为:)
答案 3 :(得分:1)
python中的所有内容都被视为对象,无论它是函数名还是类名。因此,当我们使用'def'
定义函数时,将为该方法完成内存分配。然后python将我们分配给函数的名称指向此分配的内存位置。因此,如果我们定义一个方法: -
def demo():
print 'hi'
为方法分配内存,名称'demo'
指向其内存位置,如下所示: -
现在正如zoosuck在他的第二个例子中所描述的,当你将函数名称分配给另一个变量时: -
demo2 = demo # bind to the old one
然后在这种情况下,指定的demo
内存位置也会分配给demo2
。因此,demo
和demo2
都指向同一位置12506
。
print id(demo) # will print 12506
print id(demo2) # will print 12506
现在,如果我们修改上面的代码并在下一行中,定义一个名为demo
的新方法: -
def demo():
print 'hi'
demo2 = demo # bind to the old one
demo() # Will print hi
def demo():
print "hello"
demo() # Will print hello
demo2() # Will print hi
然后为这个新方法分配了一个全新的内存位置12534
,现在demo
将指向这个新位置12534
,而不是指向旧位置,即12506
1}}。但demo2
仍指向12506
位置。
我希望这会让你清楚地知道发生了什么以及如何覆盖方法名称。
答案 4 :(得分:0)
订单很重要,如果名称相同,您定义的最后一个功能正在处理。在你的情况下,它是;
def g(x,y):
return x*y
答案 5 :(得分:0)
g
只是一个变量。它引用的对象是一个函数并不会使它在Python中变得特殊,因此您可以根据需要分配和重新分配它。在这种情况下,第二个赋值(函数定义就是这个)只是用不同的赋值替换存储在那里的对象。
答案 6 :(得分:0)
函数和方法与任何其他函数一样是普通对象。所以在
def g(x, y):
return x + y
def g(x, y):
return x * y
第二个对象g
将覆盖(替换)第一个对象,就像下面的对象a
一样:
a = 1
a = 2
参数的数量,类型或顺序没有任何区别,因为Python不支持函数/方法覆盖,并且不允许两个函数/方法具有相同的名称。
答案 7 :(得分:0)
如果您熟悉lambda function,也经常称为匿名\内联函数,这可能会让事情变得清晰
这两个代码块基本相同
def g(x,y):
return x+y
def g(x,y):
return x*y
g = lambda x,y: x+y
g = lambda x,y: x*y