I have a remote api accepting XMLs only that may be called like
api = xmlrpclib.ServerProxy(IP)
result = api.Execute({"Method": 'Method_name', "Params": [P1, P2],
... # technical values - authentication, etc
})
The technical values are not subject to change frequently - whole script would usually use same values for them, so I created a class that has a method
def call(self, method_name, params):
self.api.Execute(<constructed dictionary>)
I was wondering if it would be possible to call these methods directly as methods of self.api like:
self.api.method_name(params)
Which would in turn fill in the .Execute and the rest for me, with the general idea like:
def __getattr__(self, item):
if item in self.__dict__:
return self.item
else:
return functools.partial(self.call, method_name=item)
So, if I defined a method in class (self.foo, self.bar and the like) - calling it would produce true results of self.foo and self.bar.
Calling it like self.api.METHOD(params) where METHOD is a custom one works, but this approach "pollutes" other methods that I didn't define, like self.api.__repr__ and the like
Is it true that according to this question my approach of overriding __getitem__ is incorrect entirely? If so - how should I implement this?
I recently watched a talk by Raymond Hettinger which this post loosely reminded of, so I thought I'd link to it. I think it makes a great argument for the approach you described in you post:
Make the API work for you
First of all, I don't think overriding
__getattr__is as sinful as that post might have you believe.I like this because it's not a lot of code, and it lets us use
Executein a more convenient way (with keyword args), without relying on support for that from the internal API.Special behavior via metaclasses
The other approach prevents us having to override
__getattr__in case I've underestimated how much of a mistake it is, and it could also be considered more pythonic, as we explicitly enumerate the methods we'll be providing with our API wrapper:In reality, I don't like this, since it's little more than a very convoluted way to write:
It will save you a considerable amount of typing if you have a lot of methods though, and it's also good practice in meta-programming if you're looking to get into that or deepen your understanding of the python language.
Here's a demo with both.