I'm having a bit of an issue solving a problem I'm looking at. I have a specialized set of functions which are going to be in use across a program, which are basically dynamic callables which can replace functions and methods. Due to the need to have them work properly to emulate the functionality of methods, these functions override __get__
to provide a wrapped version that gives access to the retrieving object.
Unfortunately, __get__
does not work if the function is set directly on an instance. This is because only "data descriptors" call the __get__
function when the key is found in the __dict__
of an instance. The only solution to this that comes to mind is: trick python into thinking this is a data descriptor. This involves creating a __set__
function on the descriptor. Ideally, I want this __set__
function to work as a pass-through (returns control to the caller and continues evaluating as if it doesn't exist).
Is there any way to trick python into thinking that a descriptor is a data descriptor but letting a containing class/instance still be able to use its setattr command as normal?
Also, I am aware that it is possible to do this with an override of __getattribute__
for the caller. However, this is a bad solution because I would have to do this for the 'object' built-in and anything that overrides it. Not exactly a great solution.
Alternatively, if there is any alternative solution I would be happy to hear it.
Here is a problem example:
class Descriptor(object):
def __get__(self, obj, objtype = None):
return None
class Caller(object):
a = Descriptor()
print a
>>> None
x = Caller()
print a
>>> None
x.a = Descriptor()
print x.a
>>> <__main__.Descriptor object at 0x011D7F10>
The last case should print 'None' to maintain consistency.
If you add a __set__
to the Descriptor, this will print 'None' (as desired). However, this messes up any command of x.a = (some value) from working as it had previously. Since I do not want to mess up this functionality, that is not helpful. Any solutions would be great.
Correction: My prior idea would still not work, as I misunderstood the descriptor handling slightly. Apparently if a descriptor is not on a class at all, it will never be called- regardless of the set. The condition I had only helps if there is a dict val and a class accessor of the same name. I am actually looking for a solution more along the lines of: http://blog.brianbeck.com/post/74086029/instance-descriptors but that does not involve having everything under the sun inherit a specialized interface.
Unfortunately, given this new understanding of the descriptor interface this may not be possible? Why oh why would python make decorators essentially non-dynamic?