current position:Home>Python executes functions and even code through strings! Come and understand the operation of such a top!

Python executes functions and even code through strings! Come and understand the operation of such a top!

2021-08-23 09:33:55 Song bird

One 、 Preface

There's a need recently , Want to store the string of function name in the database , By passing it to control the execution of different functions, so as to control the business process .

Simply put, it is to call a function directly through a string , After consulting , Four feasible methods are found

Two 、 Methods to introduce

1.eval

python Built in eval The function not only matches the dictionary 、 list 、 Convert the string in Yuanzu format into a dictionary 、 List and Yuanzu ( In actual development , If you need to put json String to dictionary or list, try to use json.loads To transform , For details, please check my previous blog posts :python Handle json character string , It is recommended to use json.loads instead of eval()

You can also directly convert the code in the form of string into executable code !

For example, the following code , Will print(10000) This string directly executes :

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

Output results
 Insert picture description here


Empathy , We can go through eval To execute a function

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

Output results
 Insert picture description here


but eval It's a double-edged sword , If the string passed by the user is some code that can obtain secret information or cause security problems, it may cause great problems !
for example : The user passed in a code string to delete all files in the current directory , Then you wait to run !
 Insert picture description here


therefore eval Although powerful , But it's also dangerous ! So be careful with !!

2.locals() and globals()

locals() and globals() yes python Two built-in functions , Through them, local and global variables can be accessed in a dictionary .

The difference between the two functions is locals Is read-only , Do not modify the , and globals You can modify , for example :

y = 1
def test():
    x = 1
    locals()['x'] = 2
    globals()['y'] = 2
    print('locals Cannot modify variable , therefore x The value of is also :', x)
    print('globals Global variables can be modified , therefore y The value of is changed to :', y)
test()

Execution results

 Insert picture description here


as a result of locals() It doesn't actually return the local namespace , It returns a copy . So modify it , What's changed is the copy , It has no effect on the values of variables in the local name space .
globals() What is returned is the actual global namespace , Not a copy : And locals The behavior is completely the opposite .

Back to the topic , adopt locals and globals Call the string to execute the function :

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

Execution results
 Insert picture description here


3.getattr()

getattr() yes python Is a built-in function of , That's what we often call reflection .

getattr(Test,'func_1') It's equivalent to returning Test Class func_1 Method !

But here func_1 It can be a variable , For example, a variable representing a method name string .

for example :

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

Output results
 Insert picture description here


If getattr I didn't find this str Methods , It throws an exception , comparison eval and locals()、globals() Be safe !
 Insert picture description here


4.operator Modular methodcaller function

operator The module is python Replace functions with standard operators in , It provides a set with Python High efficiency function corresponding to the built-in operator of . for example ,operator.add(x, y) And the expression x+y identical .

It is used to implement the string access function :

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())  #  Pass parameters 
methodcaller('func_2')(Test())  #  Do not pass parameters 

Output results
 Insert picture description here


By looking at methodcaller The source code of the function can be found , It's right getattr A layer of encapsulation
 Insert picture description here


Share here for the time being , Like it, guys 、 Collection 、 Comments are my greatest support !!

copyright notice
author[Song bird],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2021/08/20210823093350040z.html

Random recommended