Python:允许没有特别定义的方法被称为ala __getattr__ [英] Python : Allowing methods not specifically defined to be called 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):
pre>
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
还有其他方法来创建包装函数。在这种情况下最简单的是使用
functools.partial
:import functools
/ pre>
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)
这将自动将所有剩余的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屋!