简体   繁体   English

通过Python中的变量调用函数

[英]Call a function through a variable in Python

I'm trying to make a game engine in Python as a "weekend project" but I have a problem. 我正在尝试用Python制作游戏引擎作为“周末项目”,但我遇到了问题。

I'm trying to make it that a user can declare a keybind by typing the key and the function into a text file what they want to run but when I run the code from that sheet with exec it runs the function and I have no idea on how to call the function through the variable. 我试图让用户可以通过在文本文件中输入键和函数来声明键绑定他们想要运行的东西,但是当我从exec运行代码时它会运行该函数而我不知道关于如何通过变量调用函数。 (Also I don't want it to run the function when it runs the code.) (我也不希望它在运行代码时运行该函数。)

Here is the code I use for executing the code from binds.zdata 这是我用来执行binds.zdata代码的代码

for line in bind:
    try:
        exec line
    except:
        try:
            error.write(localtime + " : " + "ERROR: Could not bind key from the bind file : " + line)
        except:
            pass

Here's the text in binds.zdata 这是binds.zdata中的文本

_w = Functions.motion.move().forward()
_a = Functions.motion.move().left()
_s = Functions.motion.move().back()
_d = Functions.motion.move().right()

You want to lose the () at the end of each line: 你想在每一行的末尾丢失()

_w = Functions.motion.move().forward
_a = Functions.motion.move().left
_s = Functions.motion.move().back
_d = Functions.motion.move().right

now you can call the function through the variable by simply applying parenthesis, such as: 现在你可以通过简单地应用括号来调用函数,例如:

_w()

I'm not sure I recommend "exec" since somebody could put any code in there. 我不确定我推荐“exec”,因为有人可以在那里放任何代码。

But here is your problem. 但这是你的问题。 _w = Functions.motion.move().forward() Calls the function 'forward' and puts the results in _w. _w = Functions.motion.move().forward()调用函数'forward'并将结果放入_w。 _w = Functions.motion.move().forward Assigns the function 'forward' to the variable '_w'. _w = Functions.motion.move().forward将函数'forward'赋值给变量'_w'。

Since you asked what I would do, I would create a set of tokens that represent the various functions and then let them do the mapping in side a config file (see: ConfigParser). 既然你问我会做什么,我会创建一组代表各种函数的标记,然后让它们在配置文件中进行映射(参见:ConfigParser)。 Then parse the config file. 然后解析配置文件。 It is a little more work, but a lot more secure. 这是一项更多的工作,但更安全。

I'd first change the lines in the binds.zdata file like this so they assign a function to each of the variables: 我首先更改binds.zdata文件中的行,这样他们就为每个变量分配一个函数:

_w = Functions.motion.move().forward
_a = Functions.motion.move().left
_s = Functions.motion.move().back
_d = Functions.motion.move().right

Then, assuming that Functions is defined, I'd execute all the lines in the file at once with something like: 然后,假设定义了Functions ,我会立即执行文件中的所有行,例如:

try:
    execfile('binds.zdata')
except Exception as exc:
    error.write(localtime + " : " + "ERROR: executing binds file")

Afterwards, the _w , _a , _s , _d variables will have the desired function assigned to them, which you can call as usual — ie _w() , _a() , etc. 之后, _w_a_s_d变量将分配给它们所需的函数,您可以照常调用它们 - 即_w()_a()等。

Reading the config like that with exec is going to open you to all kinds of pain at runtime, as the user's config file is going to be executable code that you are just trusting. 像exec一样读取配置会让你在运行时遇到各种各样的痛苦,因为用户的配置文件将成为你信任的可执行代码。 Malicious or unintentionally just bad commands will get execute. 恶意或无意的坏命令将被执行。 You could template it like this: 您可以像这样模板化:

def read_config(config_file):

    user_button_map = {}
    with open(config_file, 'r') as fh:
        for line in fh.readlines():
            key,func_key = line.strip().split(',')                

            assert(key in BUTTON_MAP_FUNCTIONS),"no such action"
            user_button_map[key] = BUTTON_MAP_FUNCTIONS[func_key]

    return user_button_map


BUTTON_MAP_FUNCTIONS = {
   "forward" : Functions.motion.move().forward,
   "left" : Functions.motion.move().left,
   # etc...
}

# sample config file
# w, forward
# a, left
# etc...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM