0

Is it possible in Python to get the name of property currently being accessed, modified for deleted inside the function? For example, I've got this code with some pseudo-code inside:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        prop = get_current_property() #prop is set to 'x'
        return self._x
    @x.setter
    def x(self):
        """I'm the 'x' property."""
        prop = get_current_property() #prop is set to 'x'
        return self._x


    @property
    def y(self):
        """I'm the 'x' property."""
        prop = get_current_property() #prop is set to 'y'
        return self._x

So the pseudo-code here is the get_current_property(), which should work inside of the getter, setter and deleter methods for each property. Any way to do this?

J-bob
  • 8,380
  • 11
  • 52
  • 85
  • 1
    Related: [Python code to get current function into a variable?](http://stackoverflow.com/q/4492559) – Martijn Pieters Jun 17 '14 at 16:26
  • 1
    No, you cannot, not really. The function object has no reference to itself, let alone the property object. Various tricks with introspection have been proposed, but the bottom line is: just put the name in a local variable. – Martijn Pieters Jun 17 '14 at 16:28

2 Answers2

0

So, there is no way to make it easy and sexy. Only dirty-inspecty magic, my friend.

import inspect
class A(object):
    @property
    def b(self):
        print inspect.stack()[0][3]

A().b

will give you result you want, but you should do it only if there is no way you can deal with your things.

Btw, you can try to make a decorator, which will take a function, take its __name__ and send it as argument.

Here is implementation of idea:

def named_property(func):
    return property(lambda *a, **kwa: func(*a, fname=func.__name__, **kwa))

class A(object):
    @named_property
    def b(self, fname):
        print fname
A().b  # will print 'b'
dt0xff
  • 1,553
  • 1
  • 10
  • 18
0

As @Martijn Pieters said, there is no straightforward way for the method to get a reference to itself.

I'm trying to understand why the property definition (written by you) wouldn't already know its own name. I'm guessing that you want to do this so that you can create a bunch of properties programmatically without a separate explicit defitinition for each one.

Try something like this to build a new class dynamically while creating some of its properties from a list:

def make_getter_setter(name):
    # this function uses an implicit closure to "freeze" the local value of name
    # within the scope of the getter/setter functions
    def getter(self):
        return name
    def setter(self):
        pass # your original code doesn't make clear that the setter should actually do anything

    return getter, setter    

class C(object):
    def __init__(self):
        # dictionary to store the values of the properties
        # this doesn't do anything now, but I presume you'll want to allow
        # setting the properties later, and you'll need somewhere to store
        # their values
        self._properties = {}

for name in ('spam', 'eggs', 'ham'):
    getter, setter = make_getter_setter(name)
    setattr(C, name, property(getter, setter, doc="I'm the '%s' property" % name))

foo = C()
print foo.eggs, foo.ham    # shows their values
help(foo)                  # shows their doc strings
Dan Lenski
  • 76,929
  • 13
  • 76
  • 124