2013-04-09 18 views
1

說我有像這樣如何獲得一個功能的屬性而不是調用它

def spam(): 
    spam.eggs = "Foobar" 
    #do stuff 
    return 

功能我想在另一個函數spam.eggs"Foobar")的值,而無需實際調用spam()方法,例如,

def main(): 
    print spam.eggs 

我希望它返回Foobar。然而,這顯然是行不通的,因爲我還沒有所謂的垃圾郵件(),所以我從來沒有分配spam.eggs財產,所以我必須這樣做

def main(): 
    spam() 
    print spam.eggs 

不過,我不「T要調用的spam()功能,如果我想的eggs屬性,其實,我要檢查spam()是否有雞蛋屬性,如果調用它之前等於"Foobar",例如

def main(): 
    if hasattr(spam,'eggs'): 
     if getattr(spam, 'eggs') == "Foobar": 
      spam() 

但就像之前,因爲我還沒有撥打spam我還沒有分配spam.eggs呢。

有沒有辦法做到這一點,也許與裝飾?我想保持分配有點接近的功能,所以我喜歡的東西,不喜歡

def func(): 
    setattr(spam, 'eggs', 'Foobar') 

凡我所要做的setattr()的另一種方法,除非在一個裝飾。

+1

這一切都有點太對我來說抽象。 (我假設我不是唯一一個在想「你爲什麼要這麼做?」)。也許如果你能告訴我們你想要實際做的事情,我們可能會建議一個更優雅的選擇......如果不是,那麼總是更加激勵你知道你正在解決一個真正的問題。 – mgilson 2013-04-09 20:25:13

+0

我有一個模塊,函數,我試圖動態註冊xmlrpc,像'server.register_function(function,function.attr)',其中屬性是RPC方法名稱 – ron975 2013-04-09 20:28:10

回答

3

它可以與裝飾做的方式,是:

def addEggs(func): 
    func.eggs = "foobar" 
    return func 

@addEggs 
def spam(): 
    pass 

>>> spam.eggs 
'foobar' 

如果你想能在一個參數化的方式來指定屬性名稱和/或價值,你必須寫一個更復雜的裝飾:

def addAttr(attr, value): 
    def deco(func): 
     setattr(func, attr, value) 
     return func 
    return deco 

@addAttr('attrName', 'value') 
def spam(): 
    pass 

>>> spam.attrName 
'value' 

但是,爲什麼你想這樣做的問題仍然是。如果函數屬性是有用的,那通常是因爲有一個自然的地方來設置它們 - 也就是說,其他的東西爲了自己的目的在函數上設置了屬性。如果你只是在定義函數的時候設置屬性 - 也就是說,如果屬性是函數本身的內在部分 - 看起來你可能想要更像是一個帶有方法的類。

+0

不錯...我不知道你可以做到這一點... – 2013-04-09 20:26:17

+1

@JoranBeasley - 是的,這是一個真正的裝飾器(而不是傳統的裝飾器,我傾向於認爲更多的是轉換)。但問題仍然是「爲什麼?」。你可以做'def spam():pass; spam.eggs ='foobar'' – mgilson 2013-04-09 20:28:38

+0

我喜歡這個解決方案比'def spam():pass; spam.eggs ='foobar',因爲它看起來好多了,也給了我更多的控制權,即使它看起來不是很「pythonic」,但我不知道你可以設置屬性功能。 – ron975 2013-04-09 21:09:46

1

我想你實際上想要一個靜態字段的類。自變量是局部的聲明它們的功能是沒有辦法來訪問他們要

class Spam: 
    eggs="foobar" 
    def __init__(self,*args,**kwargs): 
     # do some stuff 
     Spam.eggs = "foobared" 

print Spam.eggs 
Spam() 
print Spam.eggs 
+0

我想要的是檢查是否一個函數有一個特定的屬性,如果匹配,如果是,就調用它,而不是創建一個類。 – ron975 2013-04-09 20:25:59

1

你會得到與spam.eggs屬性簡單明瞭。順便說一句,你不必在功能內部分配屬性。你可以做

def spam(): 
    #do stuff 
    return 
spam.eggs = "Foobar" 

然後spam.eggs和垃圾郵件()將工作完全一樣

相關問題