将 obj.method({argument:value}) 映射到 obj.argument(value)
我不知道这是否有意义,但是......
我正在尝试动态地将方法分配给对象。
#translate this
object.key(value)
#into this
object.method({key:value})
更具体地说,在我的示例中,我有一个对象(我没有编写),我们将其称为电机,它具有一些通用方法集、状态和其他一些方法。有些将字典作为参数,有些则将列表作为参数。为了更改电机的速度并查看结果,我使用:
motor.set({'move_at':10})
print motor.status('velocity')
电机对象,然后将此请求格式化为 JSON-RPC 字符串,并将其发送到 IO 守护程序。 python 电机对象并不关心参数是什么,它只处理 JSON 格式和套接字。字符串 move_at 和velocity 只是可能有数百个有效参数中的两个。
我想做的是:
motor.move_at(10)
print motor.velocity()
我想以通用的方式来做,因为我有很多不同的参数可以传递。我不想做的是:
# create a new function for every possible argument
def move_at(self,x)
return self.set({'move_at':x})
def velocity(self)
return self.status('velocity')
#and a hundred more...
我对此进行了一些搜索,结果表明解决方案在于 lambda 和元编程,这是我无法理解的两个主题。
更新:
根据 user470379 的代码,我想出了以下...
# This is what I have now....
class Motor(object):
def set(self,a_dict):
print "Setting a value", a_dict
def status(self,a_list):
print "requesting the status of", a_list
return 10
# Now to extend it....
class MyMotor(Motor):
def __getattr__(self,name):
def special_fn(*value):
# What we return depends on how many arguments there are.
if len(value) == 0: return self.status((name))
if len(value) == 1: return self.set({name:value[0]})
return special_fn
def __setattr__(self,attr,value): # This is based on some other answers
self.set({attr:value})
x = MyMotor()
x.move_at = 20 # Uses __setattr__
x.move_at(10) # May remove this style from __getattr__ to simplify code.
print x.velocity()
输出:
Setting a value {'move_at': 20}
Setting a value {'move_at': 10}
10
感谢所有提供帮助的人!
I don't know if this will make sense, but...
I'm trying to dynamically assign methods to an object.
#translate this
object.key(value)
#into this
object.method({key:value})
To be more specific in my example, I have an object (which I didn't write), lets call it motor, which has some generic methods set, status and a few others. Some take a dictionary as an argument and some take a list. To change the motor's speed, and see the result, I use:
motor.set({'move_at':10})
print motor.status('velocity')
The motor object, then formats this request into a JSON-RPC string, and sends it to an IO daemon. The python motor object doesn't care what the arguments are, it just handles JSON formatting and sockets. The strings move_at and velocity are just two of what might be hundreds of valid arguments.
What I'd like to do is the following instead:
motor.move_at(10)
print motor.velocity()
I'd like to do it in a generic way since I have so many different arguments I can pass. What I don't want to do is this:
# create a new function for every possible argument
def move_at(self,x)
return self.set({'move_at':x})
def velocity(self)
return self.status('velocity')
#and a hundred more...
I did some searching on this which suggested the solution lies with lambdas and meta programming, two subjects I haven't been able to get my head around.
UPDATE:
Based on the code from user470379 I've come up with the following...
# This is what I have now....
class Motor(object):
def set(self,a_dict):
print "Setting a value", a_dict
def status(self,a_list):
print "requesting the status of", a_list
return 10
# Now to extend it....
class MyMotor(Motor):
def __getattr__(self,name):
def special_fn(*value):
# What we return depends on how many arguments there are.
if len(value) == 0: return self.status((name))
if len(value) == 1: return self.set({name:value[0]})
return special_fn
def __setattr__(self,attr,value): # This is based on some other answers
self.set({attr:value})
x = MyMotor()
x.move_at = 20 # Uses __setattr__
x.move_at(10) # May remove this style from __getattr__ to simplify code.
print x.velocity()
output:
Setting a value {'move_at': 20}
Setting a value {'move_at': 10}
10
Thank you to everyone who helped!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为返回动态创建的函数的类? IIRC,在
__getattr__
和__getattribute__
之间有一些棘手的情况需要注意,我不记得了,我确信有人会发表评论提醒我:那么应该发生的是,调用一个不存在的属性(即:
move_at
)将调用__getattr__
函数并创建一个新函数,该函数将返回(上面的set_fn
)。该函数的name
变量将绑定到传递给__getattr__
的name
参数(在此为"move_at"
案件)。然后,将使用您传递的参数(在本例中为10
)调用该新函数。编辑
使用 lambda 的更简洁版本(未经测试):
What about creating your own
__getattr__
for the class that returns a function created on the fly? IIRC, there's some tricky cases to watch out for between__getattr__
and__getattribute__
that I don't recall off the top of my head, I'm sure someone will post a comment to remind me:Then what should happen is that calling an attribute that doesn't exist (ie:
move_at
) will call the__getattr__
function and create a new function that will be returned (set_fn
above). Thename
variable of that function will be bound to thename
parameter passed into__getattr__
("move_at"
in this case). Then that new function will be called with the arguments you passed (10
in this case).Edit
A more concise version using lambdas (untested):
对此有很多不同的潜在答案,但其中许多可能涉及对象的子类化和/或编写或重写 __getattr__ 函数。
本质上,只要 python 无法以通常的方式找到属性,就会调用 __getattr__ 函数。
假设您可以对对象进行子类化,下面是您可能会执行的操作的一个简单示例(这有点笨拙,但这是一个开始):
输出:
There are a lot of different potential answers to this, but many of them will probably involve subclassing the object and/or writing or overriding the
__getattr__
function.Essentially, the
__getattr__
function is called whenever python can't find an attribute in the usual way.Assuming you can subclass your object, here's a simple example of what you might do (it's a bit clumsy but it's a start):
Output:
您似乎拥有对象的某些“属性”,可以通过 Python 设置
和查询
这些“属性” 。Python 中的一种常见方法是将这种行为映射到看似简单的属性访问。因此,我们编写
设置属性,然后简单地使用它
来查询它。这可以使用
__getattr__()
和__setattr__()
特殊方法:请注意,此代码不允许在初始化后动态创建
Motor
实例的新“真实”属性。如果需要,可以将相应的异常添加到 __setattr__() 实现中。You seem to have certain "properties" of your object that can be set by
and queried by
A common way to go in Python is to map this behaviour to what looks like simple attribute access. So we write
to set the property, and we simply use
to query it. This can easily be implemented using the
__getattr__()
and__setattr__()
special methods:Note that this code disallows the dynamic creation of new "real" attributes of
Motor
instances after the initialisation. If this is needed, corresponding exceptions could be added to the__setattr__()
implementation.不要使用函数调用语法进行设置,而是考虑使用赋值(带有=)。同样,只需使用属性语法来获取值,而不是函数调用语法。然后你可以使用 __getattr__ 和 __setattr__:
Instead of setting with function-call syntax, consider using assignment (with =). Similarly, just use attribute syntax to get a value, instead of function-call syntax. Then you can use __getattr__ and __setattr__: