Python:无论是否分配了输出,我都可以改变函数的行为吗?

2024-04-26 13:24:58 发布

您现在位置:Python中文网/ 问答频道 /正文

在Matlab中,nargout是一个变量,它告诉您是否分配了输出,所以

x = f(2);

以及

f(2);

会有不同的表现。你知道吗

在Python中也可以这样做吗?你知道吗

我有一个函数,可以打印到屏幕并返回matplotlib figure对象。我想,如果输出分配给一个变量,然后不要打印到屏幕上。你知道吗


Tags: 对象函数屏幕matplotlibfigurematlabnargout
2条回答

这里有一种方法,你可以做到这一点(我不建议这么做),但它有很多情况下是不起作用的——要使它起作用,你基本上需要分析行中的python代码,看看它在做什么,这在某种程度上是可能的,但可能总是有办法绕过它。你知道吗

import inspect, re


def func(x, noCheck=False):
  if not noCheck:
      #Get the line the function was called on.
      _, _, _, _, lines, _ = inspect.getouterframes(inspect.currentframe())[1]

      #Now we need to search through `line` to see how the function is called.

      line = lines[0].split("#")[0] #Get rid of any comments at the end of the line.

      match = re.search(r"[a-zA-Z0-9]+ *= *func\(.*\)", line) #Search for instances of `func` being called after an equals sign

      try:
        variable, functioncall = match.group(0).split("=")
        print variable, "=", functioncall, "=", eval(functioncall.strip()[:-1] + ", noCheck=True)")

      except:
        pass #print "not assigned to a variable"

  #Actually make the function do something
  return 3*x**2 + 2*x + 1

func(1) # x = func(1)
x = func(1)

另一种方法是在调用代码时检查所有设置的局部变量,并检查其中是否有设置为函数结果的变量,然后使用这些信息帮助解析python。你知道吗

或者您可以查看对象ID,并尝试这样做,但这并不简单,因为并非所有对象都以相同的方式工作(即执行a=10c=10,然后查看每个对象的ID,尽管ac是分开的,但它们是相同的。同样的情况也发生在短字符串上)

如果你能想出一种通用的方法,我很想知道你是怎么做到的,我想它需要在inspect中挖掘,而不是解析实际的代码。你知道吗

其他人提到这很复杂,但是可以用inspect来完成。您可能需要一个简单的方法,通过一个单独的函数来绘制它,或者传递一个额外的变量来表示要绘制。你知道吗

def create_plot(x):
    return plot

def display(plot):
    # show the plot

x = create_plot(2)
display(x)

绘图变量

def plot(x, show=False)
    # create the plot
    if show:
        # show the plot

plot(2, True)
x = plot(2)

仅仅创建这两个函数可能不值得花时间,而且更容易。你知道吗

就我个人而言,我认为这是丑陋的,令人讨厌的,我不认为功能应该基于捕捉返回值的东西。然而,我很好奇,我找到了一个方法。如果您将来想使用它,您可能会将其转换为decorator,但是我仍然建议您使用两个不同的方法,而不是检查输出。你知道吗

import inspect

def f(val):
    has_output = False
    frame = inspect.currentframe()
    name = frame.f_code.co_name
    outer = inspect.getouterframes(frame)[1] # may want to loop through available frames.
    for i in range(len(outer)):
        item = str(outer[i]).replace(" ", "")
        check = "="+name+"("
        if check in item and "="+check not in item: # also check assignment vs equality
            # Your method has an output
            has_output = True
            break

    if has_output:
        print("Something catches the output")
    return val*val
# end f

在许多情况下,这也行不通。如果你总是想让它工作的话,你就必须为支票做一个非常好的正则表达式。你知道吗

import my_lib

x = my_lib.f(2)

相关问题 更多 >