2014-06-16 95 views

回答

0

這聽起來像你想聲明一個匿名函數,它會返回一個對新函數對象的引用。

在Python中,您可以使用lambda獲得一個簡單的匿名函數對象,但對於複雜函數,它必須有一個名稱。但是任何函數對象實際上都是一個對象,您可以將引用傳遞給它,所以名稱無關緊要。

# lambda 
sqr = lambda n: n**2 
assert sqr(2) == 4 
assert sqr(3) == 9 

# named function 
def f(n): 
    return n**2 

sqr = f 
assert sqr(2) == 4 
assert sqr(3) == 9 

請注意,該函數確實有一個名稱,f,但名稱在這裏並不重要。我們將名稱sqr設置爲函數對象引用並使用該名稱。如果我們願意,我們可以將函數引用放入一個列表或其他數據結構中。

您可以重新使用該函數的名稱:

def f(n): 
    return n**2 
sqr = f 

def f(n): 
    return n**3 
cube = f 

所以,儘管Python並沒有真正支持全匿名函數,你可以得到相同的效果。這不是一個真正的問題,你必須給函數一個名字。

如果你真的不想要的功能有個名字,就可以解除綁定名稱:

def f(n): 
    return n**2 

lst = [f] # save function reference in a list 
del(f) # unbind the name 

現在訪問此功能的唯一方法是通過列表;該函數的名稱消失了。在Python

3

函數是對象,因爲它發生的那些對象確實有包含名稱的屬性,他們與被定義:

>>> def x(): 
...  pass 
... 
>>> print x.__name__ 
x 

所以,一個天真的方法可能是這樣的:

>>> def x(): 
...  print x.__name__ 
... 
>>> x() 
x 

這似乎工作。但是,由於您必須知道函數內部的名稱x才能這樣做,您並沒有真正獲得任何東西;你可能也只是這樣做:

def x(): 
    print "x" 

事實上,儘管,它比這更糟糕,因爲__name__屬性只是指名稱的功能是定義用。如果它被綁定到另一個名字,它不會像您期望的行爲:

>>> y = x 
>>> y() 
x 

更糟的是,如果原來的名稱不再身邊,它不會在所有的工作:

>>> del x 
>>> y() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in x 
NameError: global name 'x' is not defined 

第二個問題是你可以實際解決的問題,儘管這不太好。訣竅是寫一個裝飾,可以通過函數名把它作爲參數:

>>> from functools import wraps 
>>> def introspective(func): 
...  __name__ = func.__name__ 
...  @wraps(func) 
...  def wrapper(*args, **kwargs): 
...   return func(__name__=__name__, *args, **kwargs) 
...  return wrapper 
... 
>>> @introspective 
... def x(__name__): 
...  print __name__ 
... 
>>> x() 
x 
>>> y = x 
>>> y() 
x 
>>> del x 
>>> y() 
x 

......雖然你可以看到,你仍然只找回功能與定義的名稱,而不是現在正在發生的事情。

在實踐中,簡短的答案是「不要那樣做」。 Python的一個基本事實是對象不知道它們綁定了什麼名字(或名字) - 如果你認爲你的函數需要這些信息,那麼你做錯了什麼。

相關問題