Nat*_*man 165 python forward-declaration
是否可以在Python中转发声明一个函数?我想cmp
在声明之前使用我自己的函数对列表进行排序.
print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
Run Code Online (Sandbox Code Playgroud)
我已经组织了我的代码来cmp_configs
在调用之后放置方法的定义.它失败并出现此错误:
NameError: name 'cmp_configs' is not defined
Run Code Online (Sandbox Code Playgroud)
cmp_configs
在使用之前有没有办法"声明" 方法?这会让我的代码看起来更干净吗?
我假设有些人会试图告诉我,我应该重新组织我的代码,以便我没有这个问题.但是,有些情况下这可能是不可避免的,例如在实现某种形式的递归时.如果您不喜欢这个例子,假设我有一个案例,其中确实需要转发声明一个函数.
考虑这种情况,在Python中需要向前声明一个函数:
def spam():
if end_condition():
return end_result()
else:
return eggs()
def eggs():
if end_condition():
return end_result()
else:
return spam()
Run Code Online (Sandbox Code Playgroud)
凡end_condition
与end_result
先前已经被定义.
是重新组织代码并始终在调用之前放置定义的唯一解决方案吗?
Van*_*nya 101
你可以做的是将调用包装成自己的函数.
以便
foo()
def foo():
print "Hi!"
Run Code Online (Sandbox Code Playgroud)
会打破,但是
def bar():
foo()
def foo():
print "Hi!"
bar()
Run Code Online (Sandbox Code Playgroud)
将正常工作.
一般的规则Python
是不是该功能应该被定义的代码(如在更高Pascal
),但它应该它的使用之前定义.
希望有所帮助.
jld*_*ont 87
如果您通过以下内容启动脚本:
if __name__=="__main__":
main()
Run Code Online (Sandbox Code Playgroud)
那么你可能不必担心像"前瞻性宣言"这样的事情.你看,解释器会加载你所有的函数,然后启动你的main()函数.当然,确保你所有的进口都是正确的;-)
想想看,我从来没有在python中听到过"前向声明"这样的事情......但话又说回来,我可能错了;-)
Ric*_*chN 73
如果你不想在使用之前定义一个函数,之后定义它是不可能的,那么在其他模块中定义它呢?
从技术上讲,你仍然首先定义它,但它很干净.
您可以创建如下的递归:
def foo():
bar()
def bar():
foo()
Run Code Online (Sandbox Code Playgroud)
Python的函数是匿名的,就像值是匿名的,但它们可以绑定到一个名称.
在上面的代码中,foo()
不调用名为foo的函数,它调用恰好foo
在调用点绑定到名称的函数.可以在foo
其他地方重新定义,bar
然后调用新函数.
你的问题无法解决,因为它就像要求获得一个尚未声明的变量.
BJ *_*mer 10
如果对cmp_configs的调用在它自己的函数定义中,那么你应该没问题.我举个例子.
def a():
b() # b() hasn't been defined yet, but that's fine because at this point, we're not
# actually calling it. We're just defining what should happen when a() is called.
a() # This call fails, because b() hasn't been defined yet,
# and thus trying to run a() fails.
def b():
print "hi"
a() # This call succeeds because everything has been defined.
Run Code Online (Sandbox Code Playgroud)
通常,将代码放在函数内(例如main())将解决您的问题; 只需在文件末尾调用main()即可.
KGa*_*oir 10
我为恢复这个线程而道歉,但是这里没有讨论可能适用的策略.
使用反射可以做类似于前向声明的事情.例如,假设您有一段代码如下所示:
# We want to call a function called 'foo', but it hasn't been defined yet.
function_name = 'foo'
# Calling at this point would produce an error
# Here is the definition
def foo():
bar()
# Note that at this point the function is defined
# Time for some reflection...
globals()[function_name]()
Run Code Online (Sandbox Code Playgroud)
因此,通过这种方式,我们确定了在实际定义之前要调用的函数,实际上是前向声明.在蟒蛇的说法globals()[function_name]()
是一样的foo()
,如果function_name = 'foo'
由于上述原因的讨论,因为蟒蛇必须在调用它之前查找各项功能.如果要使用该timeit
模块来查看这两个语句的比较,它们具有完全相同的计算成本.
当然这里的例子是非常无用的,但是如果一个人需要执行一个函数的复杂结构,但必须在之前声明(或者在结构上之后没有任何意义),可以只存储一个字符串和尝试稍后调用该函数.
不,我不相信有任何方法可以在Python中转发声明一个函数.
想象一下,你是Python解释器.当你到达线
print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
Run Code Online (Sandbox Code Playgroud)
要么你知道cmp_configs是什么,要么你不知道.为了继续,你必须知道cmp_configs.如果有递归则无关紧要.
像前向声明一样在python中没有这样的东西.您只需确保在需要之前声明您的函数.请注意,在执行函数之前,不会解释函数体.
请考虑以下示例:
def a():
b() # won't be resolved until a is invoked.
def b():
print "hello"
a() # here b is already defined so this line won't fail.
Run Code Online (Sandbox Code Playgroud)
您可以认为函数的主体只是在调用函数后将被解释的另一个脚本.
小智 7
# declare a fake function (prototype) with no body
def foo(): pass
def bar():
# use the prototype however you see fit
print(foo(), "world!")
# define the actual function (overwriting the prototype)
def foo():
return "Hello,"
bar()
Run Code Online (Sandbox Code Playgroud)
输出:
# declare a fake function (prototype) with no body
def foo(): pass
def bar():
# use the prototype however you see fit
print(foo(), "world!")
# define the actual function (overwriting the prototype)
def foo():
return "Hello,"
bar()
Run Code Online (Sandbox Code Playgroud)
有时,自上而下的算法最容易理解,从整体结构开始,深入细节.
你可以在没有前瞻声明的情况下这样做
def main():
make_omelet()
eat()
def make_omelet():
break_eggs()
whisk()
fry()
def break_eggs():
for egg in carton:
break(egg)
# ...
main()
Run Code Online (Sandbox Code Playgroud)
小智 5
导入文件本身。假设该文件名为 test.py:
import test
if __name__=='__main__':
test.func()
else:
def func():
print('Func worked')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
145978 次 |
最近记录: |