Python:允许没有特别定义的方法被称为ala __getattr__ [英] Python : Allowing methods not specifically defined to be called ala __getattr__

查看:152
本文介绍了Python:允许没有特别定义的方法被称为ala __getattr__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个Python类,它能够执行以下操作:

  c = MyClass 
a = cA(A的名称)#内部调用c.create(A,A的名称)
b = cB(B的名称)# .create(B,B的名称)

A和B可以是任何好吧,它们是在数据库中定义的,但我不想在我的代码中明确定义它们)



一个简单的解决方法是, :

  class MyClass():
def __init __(self):
self.createItem =

def create(self,itemType,itemName):
print使用名称%s创建项目%s%(itemType,itemName)

def create_wrapper self,name):
self.create(self.createItem,name)

def __getattr __(self,attrName):
self.createItem = attrName
return self .create_wrapper

这将在用户调用类似时工作:

  a = cA(nameA)
b = cB(nameB)

但是,在函数指针未被调用存储的情况下,它会下降:

  aFunc = cA 
bFunc = cB
aFunc(nameA)#实际上调用c.create(B,nameA),
#as cB最后一个__getattr __()调用
bFunc(nameB)

感谢



编辑:我似乎只是想出这一个,有一个更加优雅的解决方案....



我的解决方案是:

  class MyClassCreator():
def __init __(self,origClass,itemType):
self.origClass = origClass
self.itemType = itemType

def create_wrapper (self,name):
return self.origClass.create(self.itemType,name)

class MyClass():
def __init __(self):
self.createItem =

def create(self,itemType,itemName):
print使用名称%s创建项目%s%(itemType,itemName)

def __getattr __(self,attrName):
return MyClassCreator(self,attrName).create_wrapper

我实际上最终使用的版本(因为我需要比单个参数更复杂)是:(我不知道这是否可以使用lambda函数...)

  def __getattr __(self,attrName):
def find_entity_wrapper(* args,** kwargs):
return self.find_entity ,* args,** kwargs)

return find_entity_wrapper


解决方案

__ getattr __ 返回本地包装函数:

  class MyClass(object):
def create(self,itemType,itemName):
print使用名称%s创建项目%s%(itemType,itemName)
$ b b def __getattr __(self,attrName):
def create_wrapper(name):
self.create(attrName,name)
return create_wrapper
pre>

还有其他方法来创建包装函数。在这种情况下最简单的是使用 functools.partial

  import functools 

class MyClass(object):
def create(self,itemType,itemName,* args,** kwargs):
print s,args%r和kwargs%r%(itemType,itemName,args,kwargs)

def __getattr __(self,attrName):
return functools.partial(self.create,attrName )

c = MyClass()
bFunc = cB
bFunc(nameB,1,2,foo = 3)
/ pre>

这将自动将所有剩余的args传递给包装函数。


I'm trying to write a Python class that has the ability to do the following:

c = MyClass()
a = c.A("a name for A") # Calls internally c.create("A", "a name for A")
b = c.B("a name for B") # Calls internally c.create("B", "a name for B")

A and B could be anything (well, they're defined in a database, but I don't want to explicitly define them in my code)

A hacky workaround for it would be to do the following:

class MyClass():
    def __init__(self):
        self.createItem = ""

    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def create_wrapper(self, name):
        self.create(self.createItem, name)

    def __getattr__(self, attrName):
        self.createItem = attrName
        return self.create_wrapper

This will work when the user calls something like:

a = c.A("nameA")
b = c.B("nameB")

However, it will fall over in situations where the function pointers are stored without being called:

aFunc = c.A
bFunc = c.B
aFunc("nameA") # Is actually calling c.create("B", "nameA"),
               # as c.B was the last __getattr__() call
bFunc("nameB")

Any suggestions for anything I'm missing here?

Thanks

Edit: I appear to have just figured this one out, but Philipp has a far more elegant solution....

My solution was:

class MyClassCreator():
    def __init__(self, origClass, itemType):
        self.origClass = origClass
        self.itemType = itemType

    def create_wrapper(self, name):
        return self.origClass.create(self.itemType, name)

class MyClass():
    def __init__(self):
        self.createItem = ""

    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def __getattr__(self, attrName):
        return MyClassCreator(self, attrName).create_wrapper

The version that I actually ended up using (as I needed more complexity than a single argument) is: (I don't know if this can be done using a lambda function...)

def __getattr__(self, attrName):
    def find_entity_wrapper(*args, **kwargs):
        return self.find_entity(attrName, *args, **kwargs)

    return find_entity_wrapper

解决方案

Have __getattr__ return a local wrapper function:

class MyClass(object):
    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def __getattr__(self, attrName):
        def create_wrapper(name):
            self.create(attrName, name)
        return create_wrapper

There are other ways to create the wrapper function. The simplest one in this case is to use functools.partial:

import functools

class MyClass(object):
    def create(self, itemType, itemName, *args, **kwargs):
        print "Creating item %s with name %s, args %r and kwargs %r" % (itemType, itemName, args, kwargs)

    def __getattr__(self, attrName):
        return functools.partial(self.create, attrName)

c = MyClass()
bFunc = c.B
bFunc("nameB", 1, 2, foo=3)

This will automatically pass all remaining args to the wrapped function.

这篇关于Python:允许没有特别定义的方法被称为ala __getattr__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆