是否可以修改函数代码?

时间:2019-10-28 17:39:38

标签: python

具有以下功能:

def func(var):
    print (var)

x = func

是否可以修改给定x的函数的代码?假装“编译代码”是一个字符串。我的意思是这样的:

>>> x = func
>>> x_as_string = "print (var)"
>>> x_as_string_modified = x_as_string += "\n print('end of function')"
>>> x(2)
2
end of function

4 个答案:

答案 0 :(得分:1)

您表达的方法是非常非常的坏主意。自我修改的代码弄脏了您的业障,使您远离沙托和涅磐,并且缺乏佛性。

可以做的是编写一个以受控方式参数化您的变化的函数。然后编写包装函数,以根据您的选择返回该函数的自定义变体。

def make_x(str):

    def inner(var):
        print(var)
        if str:
            print(str)

    return inner

orig = make_x(None)
new  = make_x("end of function")

orig(2)
new(77)

输出:

2
77
end of function

足够满足您的需求吗?

答案 1 :(得分:1)

我不能对此施加足够的压力:永远不要在任何严重的问题上使用它。执行是危险的,不是一个好主意。

但是好奇心使我变得更好,所以这是一种从字面上向要执行的代码添加行的方法:

>>> import inspect

    def func(var):
        print (var)

    def terriblie_idea(arg, func = func, new_func_lines = []):
        func_string, call_string =  inspect.getsource(func), f"func({arg})"
        func_string += ('\n' + '\n'.join(new_func_lines)) if new_func_lines else ''

        exec(func_string + ';\n' +call_string)

>>> terriblie_idea(124, new_func_lines=["print(f'This code is dynamic! Your input was {arg}')", "print('end of function')"])

输出:

>>> This code is dynamic! Your input was 124
    end of function
    124

这与您的想法类似,因为您可以通过将新行作为参数传递到terrible_idea函数中来将新行输入到原始函数中。对该函数进行重建,然后在terrible_idea的第一个参数上调用它,我应该提到这是一个糟糕的主意。

答案 2 :(得分:0)

您可以结合使用asyncinspect.getsource

eval

并评估:

import inspect
import os.path

os_path_join_code = inspect.getsource(os.path.join)

现在,您将所有内容放在一起并继续进行探索。但这绝对不是修改代码的最佳方法,您始终可以通过扩展代码行为来修改代码行为,并且很有可能通过预先设置的代码模式来完成。我将从了解python函数装饰器开始。

答案 3 :(得分:0)

我建议您研究所谓的python public List<WebElement> findElements(SearchContext context) { return context instanceof FindsById ? ((FindsById)context).findElementsById(this.id) : ((FindsByXPath)context).findElementsByXPath(".//*[@id = '" + this.id + "']"); }

考虑以下代码:

decorators

即使您不太了解代码,也要知道打印到控制台的文本是:

import functools

def decorator(f):
    @functools.wraps(f)
    def wrapped_f(*args, **kwargs):
        print('start of function')
        r = f(*args, **kwargs)
        print('end of function')
        return r
    return wrapped_f

@decorator
def print_strawberries():
    print("strawberries")

print_strawberries()

以某种方式,我们更改了start of function strawberries end of function 。新版本还将打印print_strawberriesstart of function

符号end of function等效于以下内容:

@decorator

功能装饰器最好是定义自己的def print_strawberries(): print("strawberries") print_strawberries = decorator(print_strawberries) 方法的类。 __call__是paren-paren运算符__call__。也就是说()实际上是print("hello world")

print.__call__("hello world")