在另一个函数内部和外部定义函数之间的区别
Difference between defining a function inside versus outside of another function
我写了一个函数 derivative(w1, w2, pt)
来计算函数 f(x) = w1 * x**3 + w2 * x - 1
在点 pt
的导数。奇怪的是,我发现根据 def f(x)
位于 derivative(w1, w2, pt)
内部还是外部,我会得到不同的结果。为什么 def f(x)
的定位很重要/哪个是正确的?
示例 1:
def derivative(w1, w2, pt):
x = sy.Symbol('x')
def f(x):
return w1 * x**3 + w2 * x - 1
# Get derivative of f(x)
def df(x):
return sy.diff(f(x),x)
# Evaluate at point x
return df(x).subs(x,pt)
来自derivative(5, 8, 2)
returns 68
.
示例 2:
def f(x):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x)
def df(x):
return sy.diff(f(x),x)
# Evaluate at point x
return df(x).subs(x,pt)
来自derivative(5, 8, 2)
returns 53
.
我认为是你的全局范围被污染了。看看这个例子:
import sympy as sy
def f(x, w1, w2):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x)
def df(x, w1, w2):
return sy.diff(f(x, w1, w2),x)
# Evaluate at point x
return df(x, w1, w2).subs(x,pt)
print(derivative(5, 8, 2))
这只是示例 2 的修改版本,returns 答案相同。
嵌套函数可以访问父函数中的局部名称。当您定义 f
outside 时,它无法访问本地 w1
和 w2
,因此它必须假设它们是 globals 代替。
如果你没有在全局级别定义 w1
和 w2
,你的第二个版本实际上会引发 NameError
:
>>> import sympy as sy
>>> def f(x):
... return w1 * x**3 + w2 * x - 1
...
>>> def derivative(w1, w2, pt):
... x = sy.Symbol('x')
... def df(x):
... return sy.diff(f(x),x)
... return df(x).subs(x,pt)
...
>>> derivative(5, 8, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in derivative
File "<stdin>", line 4, in df
File "<stdin>", line 2, in f
NameError: name 'w1' is not defined
你没有得到异常意味着你之前已经定义了w1
和w2
,并且是那些值 正被用来提供您的错误答案。
您可以 'fix' 您的第二个示例,方法是将 w1
和 w2
设置为全局变量。作为第一个和第二个参数传递给 derivative()
调用实际上并不重要,因为那些 w1
和 w2
参数值被 完全忽略:
>>> w1 = 5
>>> w2 = 8
>>> derivative('This value is ignored', 'And so is this one', 2)
68
在您的本地设置中,您 可能 将 w1
和 w2
分别设置为 4
和 5
,因为x
是 53
:
的值
>>> w1 = 4
>>> w2 = 5
>>> derivative('This value is ignored', 'And so is this one', 2)
53
对于你的第一个例子,w1
和w2
是由derivative()
当地人提供的;无论您定义了什么全局名称,都不会使用这些名称。
如果你想在derivative()
之外定义f
,仍然先把w1
和w2
传给derivative()
,那么你还需要将这些相同的值传递给 f()
函数:
def f(x, w1, w2):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x, w1, w2)
def df(x):
return sy.diff(f(x, w1, w2), x)
# Evaluate at point x
return df(x).subs(x,pt)
现在 f()
明确地从嵌套的 df()
函数接收 w1
和 w2
,而不是从全局函数接收。
我写了一个函数 derivative(w1, w2, pt)
来计算函数 f(x) = w1 * x**3 + w2 * x - 1
在点 pt
的导数。奇怪的是,我发现根据 def f(x)
位于 derivative(w1, w2, pt)
内部还是外部,我会得到不同的结果。为什么 def f(x)
的定位很重要/哪个是正确的?
示例 1:
def derivative(w1, w2, pt):
x = sy.Symbol('x')
def f(x):
return w1 * x**3 + w2 * x - 1
# Get derivative of f(x)
def df(x):
return sy.diff(f(x),x)
# Evaluate at point x
return df(x).subs(x,pt)
来自derivative(5, 8, 2)
returns 68
.
示例 2:
def f(x):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x)
def df(x):
return sy.diff(f(x),x)
# Evaluate at point x
return df(x).subs(x,pt)
来自derivative(5, 8, 2)
returns 53
.
我认为是你的全局范围被污染了。看看这个例子:
import sympy as sy
def f(x, w1, w2):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x)
def df(x, w1, w2):
return sy.diff(f(x, w1, w2),x)
# Evaluate at point x
return df(x, w1, w2).subs(x,pt)
print(derivative(5, 8, 2))
这只是示例 2 的修改版本,returns 答案相同。
嵌套函数可以访问父函数中的局部名称。当您定义 f
outside 时,它无法访问本地 w1
和 w2
,因此它必须假设它们是 globals 代替。
如果你没有在全局级别定义 w1
和 w2
,你的第二个版本实际上会引发 NameError
:
>>> import sympy as sy
>>> def f(x):
... return w1 * x**3 + w2 * x - 1
...
>>> def derivative(w1, w2, pt):
... x = sy.Symbol('x')
... def df(x):
... return sy.diff(f(x),x)
... return df(x).subs(x,pt)
...
>>> derivative(5, 8, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in derivative
File "<stdin>", line 4, in df
File "<stdin>", line 2, in f
NameError: name 'w1' is not defined
你没有得到异常意味着你之前已经定义了w1
和w2
,并且是那些值 正被用来提供您的错误答案。
您可以 'fix' 您的第二个示例,方法是将 w1
和 w2
设置为全局变量。作为第一个和第二个参数传递给 derivative()
调用实际上并不重要,因为那些 w1
和 w2
参数值被 完全忽略:
>>> w1 = 5
>>> w2 = 8
>>> derivative('This value is ignored', 'And so is this one', 2)
68
在您的本地设置中,您 可能 将 w1
和 w2
分别设置为 4
和 5
,因为x
是 53
:
>>> w1 = 4
>>> w2 = 5
>>> derivative('This value is ignored', 'And so is this one', 2)
53
对于你的第一个例子,w1
和w2
是由derivative()
当地人提供的;无论您定义了什么全局名称,都不会使用这些名称。
如果你想在derivative()
之外定义f
,仍然先把w1
和w2
传给derivative()
,那么你还需要将这些相同的值传递给 f()
函数:
def f(x, w1, w2):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x, w1, w2)
def df(x):
return sy.diff(f(x, w1, w2), x)
# Evaluate at point x
return df(x).subs(x,pt)
现在 f()
明确地从嵌套的 df()
函数接收 w1
和 w2
,而不是从全局函数接收。