Python通过字符串来执行函数甚至代码!这么顶的操作快来了解下!

简介: Python通过字符串来执行函数甚至代码!这么顶的操作快来了解下!

一、前言

最近有个需求,想在数据库中存入函数名的字符串,通过传递它来控制不同函数的执行以便业务流程的控制。


简单来说就是通过字符串来直接调用函数,经过查阅后,发现了四种比较可行的方法


二、方法介绍

1.eval

python内置的eval函数不仅可将符合字典、列表、元祖格式的字符串转换成字典、列表和元祖 (在实际开发的时候,如果需要把json字符串转字典或列表尽量使用json.loads来转化,详情可查看我之前分享的博文:python处理json字符串,建议使用json.loads而不是eval())


还可以直接将字符串形式的代码直接转化成可执行的代码!


例如如下代码,会将print(10000)这个字符串直接执行:

str1='print(10000)'
eval(str1)


输出结果

47bd71dfd5b94db2aff89e97f408072b.png

同理,我们可以通过eval来执行一个函数


def test(x, y):
    print(x + y)
eval('test(1,2)')

输出结果

9c03f039dcf54be799ef4e55d59601f8.png


但eval是把双刃剑,如果用户传递的字符串是一些能够获取隐秘信息或者带来安全问题的代码就可能带来极大的问题!

例如:用户传入了一个删除当前目录所有文件的代码字符串,那你就等着跑路吧!


00ce6a86af7848b89e0b1e8b29eca910.png


因此eval虽然强大,但是也很危险!所以要慎用!!


2.locals()和globals()


locals() 和 globals() 是python的两个内置函数,通过它们可以以字典的方式访问局部和全局变量。


两个函数的区别在于locals 是只读的,不可修改,而globals可以修改,例如:

y = 1
def test():
    x = 1
    locals()['x'] = 2
    globals()['y'] = 2
    print('locals无法对变量进行修改,所以x的值还为:', x)
    print('globals可以对全局变量进行修改,所以y的值被改为:', y)
test()

执行结果


299080be113a42e4a912eee6d480c948.png

原因是locals()实际上没有返回局部名字空间,它返回的是一个拷贝。所以对它进行修改,修改的是拷贝,而对实际的局部名字空间中的变量值并无影响。

globals()返回的是实际的全局名字空间,而不是一个拷贝: 与 locals 的行为完全相反。


回到主题,通过locals和globals调用字符串来执行函数:


def test(x, y):
    print(x + y)
locals()['test'](1, 2)
print("-----------------")
globals()['test'](1, 2)

执行结果


34878c52c6884306937e1a45c891e95e.png

3.getattr()


getattr() 是python的内建函数,也就是我们常说的反射。

getattr(Test,'func_1') 就相当于返回Test类中的func_1方法!

但是这里 func_1可以为变量,比如一个表示方法名字符串的变量。

例如:

class Test:
    def fuc_1(self, x,y):
        print(x+y)
getattr(Test(), 'fuc_1')(1,2)

输出结果

3877b806407043f9acd72fa92e9bb06c.png

如果getattr没有找到这个str的方法,会抛出异常,相比eval和locals()、globals()要安全一些!

c03d63e936954cf19f157a3a60836c32.png


4.operator模块的methodcaller函数


operator模块是python中的标准运算符替代函数,它提供了一套与Python的内置运算符对应的高效率函数。例如,operator.add(x, y) 与表达式 x+y 相同。

通过它来实现字符串访问函数:

from operator import methodcaller
class Test:
    def func_1(self, x, y):
        print("func_1")
        print(x + y)
    def func_2(self):
        print("func_2")
methodcaller('func_1', 1, 2)(Test())  # 传递参数
methodcaller('func_2')(Test())  # 不传递参数

输出结果

955a97a3285f4dac8a2c7ef3f6c06eb2.png


通过查看methodcaller函数的源码可以发现,它是对getattr进行了一层封装

2852574be0854ca4a983970ab144019a.png

目录
相关文章
|
6天前
|
索引 Python
python字符串类型及操作
本文主要讲解字符串类型的表示、操作符、处理函数、处理方法及格式化。内容涵盖字符串的定义、表示方法(单双引号、三引号)、索引与切片、特殊字符转义、常见操作符(如+、*、in等)、处理函数(如len()、str()、chr()等)、处理方法(如.lower()、.split()等)以及格式化方式(如.format())。通过实例代码详细介绍了字符串的各种用法和技巧,帮助读者全面掌握字符串操作。
python字符串类型及操作
|
14天前
|
开发者 Python
Python入门:8.Python中的函数
### 引言 在编写程序时,函数是一种强大的工具。它们可以将代码逻辑模块化,减少重复代码的编写,并提高程序的可读性和可维护性。无论是初学者还是资深开发者,深入理解函数的使用和设计都是编写高质量代码的基础。本文将从基础概念开始,逐步讲解 Python 中的函数及其高级特性。
Python入门:8.Python中的函数
|
6天前
|
C语言 Python
Python学习:内建属性、内建函数的教程
本文介绍了Python中的内建属性和内建函数。内建属性包括`__init__`、`__new__`、`__class__`等,通过`dir()`函数可以查看类的所有内建属性。内建函数如`range`、`map`、`filter`、`reduce`和`sorted`等,分别用于生成序列、映射操作、过滤操作、累积计算和排序。其中,`reduce`在Python 3中需从`functools`模块导入。示例代码展示了这些特性和函数的具体用法及注意事项。
|
6天前
|
Go Python
Python中的round函数详解及使用示例
`round()`函数是Python内置的用于四舍五入数字的工具。它接受一个数字(必需)和可选的小数位数参数,返回最接近的整数或指定精度的浮点数。本文详细介绍其用法、参数及示例,涵盖基本操作、负数处理、特殊情况及应用建议,帮助你更好地理解和运用该函数。
|
5天前
|
数据采集 供应链 API
实战指南:通过1688开放平台API获取商品详情数据(附Python代码及避坑指南)
1688作为国内最大的B2B供应链平台,其API为企业提供合法合规的JSON数据源,直接获取批发价、SKU库存等核心数据。相比爬虫方案,官方API避免了反爬严格、数据缺失和法律风险等问题。企业接入1688商品API需完成资质认证、创建应用、签名机制解析及调用接口四步。应用场景包括智能采购系统、供应商评估模型和跨境选品分析。提供高频问题解决方案及安全合规实践,确保数据安全与合法使用。立即访问1688开放平台,解锁B2B数据宝藏!
|
6天前
|
API 开发工具 Python
【Azure Developer】编写Python SDK代码实现从China Azure中VM Disk中创建磁盘快照Snapshot
本文介绍如何使用Python SDK为中国区微软云(China Azure)中的虚拟机磁盘创建快照。通过Azure Python SDK的Snapshot Class,指定`location`和`creation_data`参数,使用`Copy`选项从现有磁盘创建快照。代码示例展示了如何配置Default Azure Credential,并设置特定于中国区Azure的`base_url`和`credential_scopes`。参考资料包括官方文档和相关API说明。
|
2月前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
74 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
7天前
|
人工智能 数据库连接 开发工具
[oeasy]python069_当前作用域都有些什么_列表dir_函数_builtins
本文介绍了Python中`dir()`函数的使用方法及其作用。`dir()`可以列出当前作用域内的所有变量和成员,类似于`locals()`,但`dir()`不仅限于本地变量,还能显示模块中的所有成员。通过`dir(__builtins__)`可以查看内建模块中的所有内建函数,如`print`、`ord`、`chr`等。此外,还回顾了`try-except-finally`结构在数据库连接中的应用,并解释了为何`print`函数可以直接使用而无需导入,因为它位于`__builtins__`模块中。最后,简要提及了删除`__builtins__.print`的方法及其影响。
22 0
|
3月前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
85 33
|
2月前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
35 3

热门文章

最新文章