【问题标题】:Dynamically generate method from string?从字符串动态生成方法?
【发布时间】:2013-10-09 15:13:44
【问题描述】:

我有一个不同类型的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 仅在对象中定义一次,相关函数通过操作对象函数列表从它派生。

这样的事情可能吗?

【问题讨论】:

  • sizetotal 有什么关系?
  • 我不确定是否理解问题,但您需要getattr__getitem__
  • 您可以这样做 - 但您希望通过目前的方法获得什么?

标签: python function object


【解决方案1】:

虽然当然可以从类中获取未知属性作为属性,但这不是 Python 方法(__getattr__ 魔术方法更像是 ruby​​ist)

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

【讨论】:

  • 非常感谢!这就是我一直在寻找的;像魅力一样工作!
  • @Thomas “虽然可以从类中获取未知属性作为属性,但这不是 Python 方法”的意思是“虽然你可以制作特殊的语言语法,但其他人都会有一个很难理解它”。所以“像魅力一样工作”可能更准确地说是“这周对我来说像魅力一样工作”。
【解决方案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) 创建了实例,那么该方法将被第一种方法覆盖。

【讨论】:

    【解决方案3】:
    >>> 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
    

    【讨论】:

    • 这有什么帮助? (甚至与问题相似?)
    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多