2011-06-05 13 views
1

我想在python中爲外部模塊編寫包裝器。該模塊提供了一種方法來共軛預期2個參數的動詞。我想將它包裝成幾種方法,我想知道是否有方法以編程方式進行。如何動態克隆類方法,但能夠在Python中區分它們

即代替:

class X: 
    def a(self,arg): 
    return module.do(arg,'a') 
    def b(self,arg): 
    return module.do(arg,'b') 
    ... 
    def z(self,arg): 
    return module.do(arg,'z') 

我試圖做的事:

class X: 
    def a(self,arg): 
    return module.do(arg,__name__) 
    return module.do(arg,__name__) 
    def __init__(self): 
    setattr(self,'b',self.a) 
    ... 
    setattr(self,'z',self.a) 
x = X() 
x.a(y) 
x.b(y) 
x.z(y) 

的問題是,返回前水平的方法,而不是當前。 我都嘗試:

from inspect import stack 
stack()[0][3] 
import sys 
sys._getframe().f_code.co_name 

但是當我打電話B()或Z()我得到 'A'。 我做錯了什麼?有沒有其他方法可以達到類似的結果?

+0

爲什麼不只是包裝「做」的一項新功能,需要一個字符串參數? – katrielalex 2011-06-05 17:49:59

回答

1

你只是簡單地將所有類的bz屬性指向a方法。這意味着每當有人訪問instance.b時,它會給出a方法(這就是爲什麼co_name總是a)。

可以完成你想要這樣的東西:

import string 

class X(object): 
    def __getattr__(self, name): 
    if name in string.lowercase and len(name) == 1: 
     def call_into_module(arg): 
     return module.do(arg, name) 
     return call_into_module 

    return super(X, self).__getattr__(name) 
+0

這正是我所需要的。非常感謝你。我不知道我可以覆蓋getattr – 2011-06-05 18:06:26

+0

@Cameron:'string.lowercase'中的名字是用來檢查'name'是否是單個小寫字母?它沒有。 – 2011-06-05 18:12:32

+0

@Sven:好點?謝謝你打電話給我:-) – Cameron 2011-06-05 18:20:14

3

你可以做這樣的事情

class X: 
    pass 
for name in "abcdefghij": 
    setattr(X, name, lambda self, arg, _name=name: module.do(arg, _name)) 

這足以補充方法的類一次 - 它沒有必要在__init__()這樣做的每一個實例。

也許是更好的選擇是覆蓋__getattr__()

class X: 
    def __getattr__(self, name): 
     def foo(arg): 
      return module.do(arg, name) 
     return foo 
+0

第二種選擇是我正在尋找的。謝謝。 – 2011-06-05 18:07:37

相關問題