在将exec()函数放入程序之前,我有一个程序来测试它的行为。我希望最后我会收到一个由b="last_trade_id"
(在下面的例子中是13621701)表示的数字,但我得到的只是None
或ost_tranzakcja
{
"last_trade_id": 13621701,
"product_id": "BTC-EUR",
"sequence": 3542855617,
"time": "2018-04-01T18:38:32.455000Z",
"type": "heartbeat"
}
printed [a] before exec: ost_tranzakcja
printed [a] after exec: ost_tranzakcja
printed [a] after modified exec: None
printed [a] after local exec: None
printed [a] after modified local exec: None
printed [a]without and after exec: : None
下面是我用来测试的程序:
import time
import json
from websocket import create_connection
ws=create_connection("wss://ws-feed.gdax.com")
ws.send(json.dumps({"type": "subscribe", "channels": [{"name": "heartbeat", "product_ids": ["BTC-EUR"],}]}))
def KonektorWebsocket():
dane=ws.recv()
dane=json.loads(dane)
print(json.dumps(dane, indent=4, sort_keys=True))
a='ost_tranzakcja'
b="last_trade_id"
exec("print('printed [a] before exec:', a)")
exec("a=dane.get('"+ b +"', None)")
exec("print('printed [a] after exec:', a)")
a=exec("dane.get('"+ b +"', None)")
exec("print('printed [a] after modified exec:', a)")
exec("a=dane.get('"+ b +"', None)",locals())
exec("print('printed [a] after local exec:', a)")
a=exec("dane.get('"+ b +"', None)",locals())
exec("print('printed [a] after modified local exec:', a)")
print("printed [a]without and after exec: ", a)
while True:
KonektorWebsocket()
time.sleep(0.15)
有两个问题,我怀疑使你的代码不做你想要的。主要问题是不能使用
exec
直接修改函数中的局部变量。如果您在模块的顶层(全局和局部名称空间相同)运行它,那么它可以修改全局变量。但是函数中的局部变量在Python中得到了特殊的处理,不能总是把它们弄乱。你知道吗除了一个
exec
调用外,其他所有调用都在修改locals()
返回的字典(默认情况下,当不传递名称空间字典时,或者当显式传递它locals()
)。不幸的是,对函数中locals()
的修改对名称空间中的实际变量没有任何影响,只是(暂时)在dictionary对象中。当locals()
再次被调用并且命名空间中的实际值再次保存到字典中时,修改将被撤消。你知道吗所以大多数
exec
调用根本没有效果。它们不会修改a
,所以您会一直打印出它以前的值(要么是您初始化它的值,要么是在赋值之后None
,原因我将在下面解释)。你知道吗另一个问题是在您进行的“modified”exec调用中,您将返回值从
exec
分配到a
。这并不是你所期望的。exec
函数总是返回None
,这就是a
对函数其余部分的值。你知道吗如果要计算Python表达式并返回它,请使用
eval
而不是exec
。但是不能将语句放在eval
中(因此只有“modified”调用才能像编写的那样工作)。你知道吗以下是一些适合您的方法:
如果有其他选择的话,使用
eval
或exec
通常是个坏主意。您肯定不应该exec
任何您不完全信任的字符串,因为它可以运行任意Python代码。你的例子太简单了,不太清楚你到底想达到什么目的,但我很肯定,对于你真正的目标,会有比exec
更好的解决方案。你知道吗因为我的上一个示例代码过于简化,所以我提供了一个新的更复杂的版本,它可以工作并完成我想要它做的事情。(当然,除非有一种方法可以用更少的代码实现)
相关问题 更多 >
编程相关推荐