有沒有一種方法可以在函數內知道該函數是被自己調用還是賦值給一個變量=?函數可以知道它是如何被調用的嗎?
我願做這樣的事情:
def func():
if 'assigned with equal':
return 5
else:
print 'not assigned'
,會給那些輸出:
func()
-> 'not assigned'
a = func()
a
-> 5
有沒有一種方法可以在函數內知道該函數是被自己調用還是賦值給一個變量=?函數可以知道它是如何被調用的嗎?
我願做這樣的事情:
def func():
if 'assigned with equal':
return 5
else:
print 'not assigned'
,會給那些輸出:
func()
-> 'not assigned'
a = func()
a
-> 5
是的,有一種方法可以做到這一點,雖然得到它的權利將是非常棘手。您可以使用inspect
模塊訪問調用堆棧。這使您可以查看代碼看起來像是什麼的函數。
堆棧看起來是這樣的:
[(<frame object at 0x107de1d38>, 'path/to/function/file.py', 6, 'func', ['\tstack = inspect.stack()\n'], 0), (<frame object at 0x107d34050>, 'path/to/calling/file.py', 17, '<module>', ['func()\n'], 0)]
通知倒數第二項:['func()\n']
。這顯示了調用你的函數的代碼。即使函數的名稱顯示在堆棧中的其他位置,它總是顯示函數的實際名稱,無論它如何被調用。所以你必須自己做一些工作,以確定是否直接或通過分配的變量進行調用。
這是獲取函數名稱的唯一方法。 Python does not have a feature從函數本身中檢索函數名稱。
爲了說清楚這將比if func_name in stack
更加困難,我已經充實了這個函數,以展示一些關於如何調用函數以及它看起來像什麼的真實世界示例。由於該函數無法確定自己的名稱,因此它在函數的頂部被硬編碼。
import inspect
def func(var=None, default=''):
my_name = 'func'
stack = inspect.stack()
func_call = stack[-1][4][0]
print func_call.rstrip() # `func_call` contains a trailing newline
# logic to determine if the name matches
# ...
# ...
x = func
func()
return_value = x(var=1)
print func()
if x():
pass
此打印:
func()
return_value = x(var=1)
print func()
None # This prints from the call, because `func()` doesn't return anything
if x():
這裏是一個正在運行的例子,我根據公認的答案寫道。我們不能爲該功能指定一個新的名稱,但它做我想做的事
import inspect
# generator function to get all the strings in an iterable object
def descend_strings(obj):
if hasattr(obj,'__iter__'):
if type(obj)==dict:
for key in obj:
for result in descend_strings(obj[key]):
yield result
else:
for item in obj:
for result in descend_strings(item):
yield result
if type(obj)==str:
yield obj
def func():
stack = inspect.stack()
joined_flat_stack_str = ''.join(list(descend_strings(stack)))
if ('= func()' in joined_flat_stack_str) or ('print func()' in joined_flat_stack_str):
return 5
else:
print 'not assigned'
func() # 'not assigned'
a = func()
print a # 5
print func() # 5
x = func
x() # 'not assigned'
a = x() # 'not assigned'
print a # None
這是相當有限的。 'a,b = spam(),func()'或'x = spam(func())'是返回值被分配/使用但未被您的檢查識別的情況。這個'func()'有一個非常奇怪和令人驚訝的API。 – BlackJack
這是不可能的。 –
我不會嘗試這樣做。有1個版本返回,然後在呼叫站點打印返回值(如有必要)。一般來說,您應該嘗試讓函數始終返回相同的類型,或者至少一致地返回可用值或不返回。 – Carcigenicate
在類的情況下,你可以通過分配一個類變量來完成它。 – Thameem