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