从字符串动态生成方法?

时间:2013-10-09 15:13:44

标签: python function object

我有dict种不同的类型,我想根据实际参数的名称添加一个简单的getter。

例如,对于三个存储参数,我们说:

self.storage = {'total':100,'used':88,'free':1}

我现在正在寻找一种方法(如果可能的话)来动态生成一个带有一些元编程魔法的函数。

而不是

class spaceObj(object):
    def getSize(what='total'):
      return storage[what]

或硬编码

@property
def getSizeTotal():
  return storage['total']

class spaceObj(object):
# manipulting the object's index and magic
@property
def getSize: 
    return ???

这样就可以派生出调用mySpaceObj.getSizeFree - getSize只在对象中定义一次,并通过操作对象函数列表从它派生的相关函数。

这样的事情可能吗?

3 个答案:

答案 0 :(得分:5)

虽然当然可以从类中获取未知属性作为属性,但这不是pythonic方法(__getattr__魔术方法相当rubyist)

class spaceObj(object):
    storage = None

    def __init__(self):  # this is for testing only
        self.storage = {'total':100,'used':88,'free':1}

    def __getattr__(self, item):
        if item[:7] == 'getSize':  # check if an undefined attribute starts with this
            return self.getSize(item[7:])

    def getSize(self, what='total'):
        return self.storage[what.lower()]

print (spaceObj().getSizeTotal)  # 100

答案 1 :(得分:2)

您可以将值作为属性放入对象:

class SpaceObj(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

storage = {'total':100,'used':88,'free':1}
o = SpaceObj(**storage)
print o.total

o = SpaceObj(total=100, used=88, free=1)
print o.total

或使用__getattr__

class SpaceObj(object):
    def __init__(self, **kwargs):
        self.storage = kwargs

    def __getattr__(self,name):
        return self.storage[name]

o = SpaceObj(total=100, used=88, free=1)
print o.total

后一种方法需要更多的代码,但它更安全;如果您有一个方法foo并且某人使用SpaceObj(foo=1)创建了该实例,那么该方法将被第一种方法覆盖。

答案 2 :(得分:-2)

>>> import new
>>> funcstr = "def wat(): print \"wat\";return;"
>>> funcbin = compile(funcstr,'','exec')
>>> ns = {}
>>> exec funcbin in ns
>>> watfunction = new.function(ns["wat"].func_code,globals(),"wat")
>>> globals()["wat"]=watfunction
>>> wat()
wat