方法覆盖?
Method Overriding?
我看到了这段代码:
def g(x,y):
return x+y
def g(x,y):
return x*y
x,y=6,7
print (g(x,y))
输出显然(但对我来说不是)是 42。有人可以解释一下这种行为吗?我想这是方法重写,但我仍然没有得到这里的流程。
问题在于函数定义的顺序。
这在技术上不是方法覆盖,因为它需要 class 继承,而是 python 声明和引用函数的结果。
声明函数时,python 将对该函数的引用存储在以函数定义命名的变量中。 (例如,对于 "def foo():",变量将是 "foo")
通过两次声明该函数,该变量的值将被第二个定义覆盖。
当你定义一个函数,然后重新定义它,它会使用你最后定义的,即使参数不同:
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
顺序很重要,如果名称相同,则您定义的最后一个函数正在处理。在你的情况下是;
def g(x,y):
return x*y
g
只是一个变量。它所引用的对象是一个函数这一事实并没有使它在 Python 中变得特殊,因此您可以根据需要对其进行分配和重新分配。在这种情况下,第二个赋值(即函数定义)只是用另一个对象替换存储在那里的对象。
一个Python脚本从上到下解析。
因此,只要出现相同名称的变量或函数或 class,它就会覆盖之前与该名称关联的所有定义。
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。
显然不能调用 :)
函数和方法与其他任何对象一样都是普通对象。所以在
def g(x, y):
return x + y
def g(x, y):
return x * y
第二个对象 g
将覆盖(替换)第一个对象,就像下面对象 a
所做的那样:
a = 1
a = 2
参数的数量、类型或顺序没有任何区别,因为Python不支持function/method覆盖并且不允许两个functions/methods同名。
如果您熟悉 lambda function,也经常称为 anonymous\inline 函数,这可能会让事情变得更清楚一些
这两个代码块本质上是相等的
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
python 中的所有内容都被视为对象,无论是函数名称还是 class 名称。所以,当我们使用 'def'
定义一个函数时,内存分配是为该方法完成的。然后 python 将我们分配给函数的名称指向这个分配的内存位置。所以如果我们定义一个方法:-
def demo():
print 'hi'
为方法分配内存,名称'demo'
指向其内存位置如下:-
现在,正如 在他的第二个示例中所描述的那样,当您将函数名称分配给另一个变量时:-
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
。但是 demo2
仍然指向位置 12506
.
我希望这能让您清楚地了解正在发生的事情以及方法名称如何 over-written。
我看到了这段代码:
def g(x,y):
return x+y
def g(x,y):
return x*y
x,y=6,7
print (g(x,y))
输出显然(但对我来说不是)是 42。有人可以解释一下这种行为吗?我想这是方法重写,但我仍然没有得到这里的流程。
问题在于函数定义的顺序。
这在技术上不是方法覆盖,因为它需要 class 继承,而是 python 声明和引用函数的结果。
声明函数时,python 将对该函数的引用存储在以函数定义命名的变量中。 (例如,对于 "def foo():",变量将是 "foo")
通过两次声明该函数,该变量的值将被第二个定义覆盖。
当你定义一个函数,然后重新定义它,它会使用你最后定义的,即使参数不同:
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
顺序很重要,如果名称相同,则您定义的最后一个函数正在处理。在你的情况下是;
def g(x,y):
return x*y
g
只是一个变量。它所引用的对象是一个函数这一事实并没有使它在 Python 中变得特殊,因此您可以根据需要对其进行分配和重新分配。在这种情况下,第二个赋值(即函数定义)只是用另一个对象替换存储在那里的对象。
一个Python脚本从上到下解析。 因此,只要出现相同名称的变量或函数或 class,它就会覆盖之前与该名称关联的所有定义。
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。 显然不能调用 :)
函数和方法与其他任何对象一样都是普通对象。所以在
def g(x, y):
return x + y
def g(x, y):
return x * y
第二个对象 g
将覆盖(替换)第一个对象,就像下面对象 a
所做的那样:
a = 1
a = 2
参数的数量、类型或顺序没有任何区别,因为Python不支持function/method覆盖并且不允许两个functions/methods同名。
如果您熟悉 lambda function,也经常称为 anonymous\inline 函数,这可能会让事情变得更清楚一些
这两个代码块本质上是相等的
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
python 中的所有内容都被视为对象,无论是函数名称还是 class 名称。所以,当我们使用 'def'
定义一个函数时,内存分配是为该方法完成的。然后 python 将我们分配给函数的名称指向这个分配的内存位置。所以如果我们定义一个方法:-
def demo():
print 'hi'
为方法分配内存,名称'demo'
指向其内存位置如下:-
现在,正如
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
。但是 demo2
仍然指向位置 12506
.
我希望这能让您清楚地了解正在发生的事情以及方法名称如何 over-written。