类内的python函数调用

类内的python函数调用,python,function,oop,methods,Python,Function,Oop,Methods,我有一个有趣的要求。假设我有一个名为Object的类,它有两个方法,func1()和func2()。第二个方法调用func1(),尽管我希望能够更改func1()的函数定义,但我希望能够区分从func2()内部调用与作为对象类的独立方法调用,如下所示: obj = Object() obj.func1() 我可以简单地创建函数的两个版本(一个私有方法供func2()使用,一个公共方法供用户访问;是的,我知道在python中确实没有私有的东西,但遵循正常的命名约定,我可以清楚地表明它只用于内部函

我有一个有趣的要求。假设我有一个名为Object的类,它有两个方法,func1()和func2()。第二个方法调用func1(),尽管我希望能够更改func1()的函数定义,但我希望能够区分从func2()内部调用与作为对象类的独立方法调用,如下所示:

obj = Object()
obj.func1()
我可以简单地创建函数的两个版本(一个私有方法供func2()使用,一个公共方法供用户访问;是的,我知道在python中确实没有私有的东西,但遵循正常的命名约定,我可以清楚地表明它只用于内部函数)。但这需要相当数量的冗余,如果可能的话,我希望尽量避免这种情况。有没有任何人可以推荐的机制或策略来做这类事情

例如,我知道,如果我想让我的整个script object.py在仅作为独立脚本运行时执行某一组代码(即,它不会在另一个脚本的顶部导入),我会:

if __name__ == "__main__":
    ...
    code to run if standalone
    ...

我想知道对于类的方法是否有类似的策略。

您可以使用
sys.\u getframe()
并根据调用方决定要做什么
f_code.co_name
返回函数

导入系统 类MyClass(对象): def func1(自我): frame=sys.\u getframe(1) 如果frame.f_code.co_name==“func2”: 打印“从func2调用” 其他: 打印“从其他地方调用” def func2(自我): self.func1() c=MyClass() c、 func1() c、 func2()
您可以使用
sys.\u getframe()
并根据调用者决定要做什么
f_code.co_name
返回函数

导入系统 类MyClass(对象): def func1(自我): frame=sys.\u getframe(1) 如果frame.f_code.co_name==“func2”: 打印“从func2调用” 其他: 打印“从其他地方调用” def func2(自我): self.func1() c=MyClass() c、 func1() c、 func2()
您也可以像这样使用
检查

import inspect

def func2():
    if inspect.stack()[1][3] == "func1":
        #...do something...
    else:
        #...do something else...

def func1():
    return func2()
import os
import sys

def suppress_print(f, *args, **kwargs):
    """Call the function f, but print to the null device 
    instead of the screen."""
    old_stdout = sys.stdout
    sys.stdout = open(os.devnull, 'w')

    result = f(*args, **kwargs)

    sys.stdout = old_stdout

    return result

class Foo:

    def bar(self):
        print "This is a test."
        return 42

    def baz(self):
        return suppress_print(self.bar)


foo = Foo()

# this should print to the terminal
foo.bar()

# this shouldn't
foo.baz()
有关详细信息,请参阅官方文档:


您也可以像这样使用
inspect

import inspect

def func2():
    if inspect.stack()[1][3] == "func1":
        #...do something...
    else:
        #...do something else...

def func1():
    return func2()
import os
import sys

def suppress_print(f, *args, **kwargs):
    """Call the function f, but print to the null device 
    instead of the screen."""
    old_stdout = sys.stdout
    sys.stdout = open(os.devnull, 'w')

    result = f(*args, **kwargs)

    sys.stdout = old_stdout

    return result

class Foo:

    def bar(self):
        print "This is a test."
        return 42

    def baz(self):
        return suppress_print(self.bar)


foo = Foo()

# this should print to the terminal
foo.bar()

# this shouldn't
foo.baz()
有关详细信息,请参阅官方文档:


通过阅读您的评论,您的实际问题似乎是:您有一个打印某些输出的方法。如果用户调用代码,那么您希望将该输出打印到终端。如果代码由另一个方法在内部调用,则不希望打印输出

@mgilson建议的
debug
arg是一个很好的选项,但是不管出于什么原因,您都希望用户不知道这个选项

另一种方法是在函数调用过程中制作一个函数包装器来重定向
stdout
,然后恢复它。大概是这样的:

import inspect

def func2():
    if inspect.stack()[1][3] == "func1":
        #...do something...
    else:
        #...do something else...

def func1():
    return func2()
import os
import sys

def suppress_print(f, *args, **kwargs):
    """Call the function f, but print to the null device 
    instead of the screen."""
    old_stdout = sys.stdout
    sys.stdout = open(os.devnull, 'w')

    result = f(*args, **kwargs)

    sys.stdout = old_stdout

    return result

class Foo:

    def bar(self):
        print "This is a test."
        return 42

    def baz(self):
        return suppress_print(self.bar)


foo = Foo()

# this should print to the terminal
foo.bar()

# this shouldn't
foo.baz()

然后,无论何时在内部调用该函数,都要用
suppress\u print
将其包装,输出将被压缩。请注意,这实际上是一个使用上下文管理器的好地方,但我将把它留作进一步练习…

通过阅读您的评论,您的实际问题似乎是:您有一个方法可以打印一些输出。如果用户调用代码,那么您希望将该输出打印到终端。如果代码由另一个方法在内部调用,则不希望打印输出

@mgilson建议的
debug
arg是一个很好的选项,但是不管出于什么原因,您都希望用户不知道这个选项

另一种方法是在函数调用过程中制作一个函数包装器来重定向
stdout
,然后恢复它。大概是这样的:

import inspect

def func2():
    if inspect.stack()[1][3] == "func1":
        #...do something...
    else:
        #...do something else...

def func1():
    return func2()
import os
import sys

def suppress_print(f, *args, **kwargs):
    """Call the function f, but print to the null device 
    instead of the screen."""
    old_stdout = sys.stdout
    sys.stdout = open(os.devnull, 'w')

    result = f(*args, **kwargs)

    sys.stdout = old_stdout

    return result

class Foo:

    def bar(self):
        print "This is a test."
        return 42

    def baz(self):
        return suppress_print(self.bar)


foo = Foo()

# this should print to the terminal
foo.bar()

# this shouldn't
foo.baz()

然后,无论何时在内部调用该函数,都要用
suppress\u print
将其包装,输出将被压缩。请注意,这实际上是一个使用上下文管理器的好地方,但我将把它留作进一步练习…

这在非黑客方式下是不可能的。为什么你觉得你需要这样做?除了创建单独的方法外,另一种可能是在调用函数时可以使用
func2
的函数中添加一个参数,以表示“内部”使用。诀窍是将冗余代码分解成一个单独的“公共”函数,两者都可以使用。我觉得我需要这样做,因为调用时使用了某种方式,我希望生成终端输出,而如果在内部调用此函数,我希望它放弃打印到终端。在类上设置
debug
属性。使用
self.debug=True
,然后打印到终端,否则不要打印。@mgilson实际上这听起来是个不错的策略。装饰师呢?我能以某种方式使用它吗?我认为重构是好的,但这需要一点时间。这在非黑客的方式下是不可能的。为什么你觉得你需要这样做?除了创建单独的方法外,另一种可能是在调用函数时可以使用
func2
的函数中添加一个参数,以表示“内部”使用。诀窍是将冗余代码分解成一个单独的“公共”函数,两者都可以使用。我觉得我需要这样做,因为调用时使用了某种方式,我希望生成终端输出,而如果在内部调用此函数,我希望它放弃打印到终端。在类上设置
debug
属性。使用
self.debug=True
,然后打印到终端,否则不要打印。@mgilson实际上这听起来是个不错的策略。装饰师呢?我能以某种方式使用它吗?我认为重构是好的,但这需要一点时间。你愿意制作一个包含两个函数的裸体示例类来实现它吗?@astromax见我的答案中添加的示例太好了,这是