2

I have a dict of different types for which I want to add a simple getter based on the name of the actual parameter.

For example, for three storage parameters, let's say:

self.storage = {'total':100,'used':88,'free':1}

I am looking now for a way (if possible?) to generate a function on the fly with some meta-programming magic.

Instead of

class spaceObj(object):
    def getSize(what='total'):
      return storage[what]

or hard coding

@property
def getSizeTotal():
  return storage['total']

but

class spaceObj(object):
# manipulting the object's index and magic
@property
def getSize: 
    return ???

so that calling mySpaceObj.getSizeFree would be derived - with getSize only defined once in the object and related functions derived from it by manipulating the objects function list.

Is something like that possible?

3
  • How is size and total related? Commented Oct 9, 2013 at 15:16
  • I am not sure to understand the question, but you need either getattr, or __getitem__ Commented Oct 9, 2013 at 15:16
  • 1
    You could do that - but what do you hope to gain over your current approach? Commented Oct 9, 2013 at 15:18

3 Answers 3

5

While certainly possible to get an unknown attribute from a class as a property, this is not a pythonic approach (__getattr__ magic methods are rather rubyist)

class spaceObj(object):
    storage = None

    def __init__(self):  # this is for testing only
        self.storage = {'total':100,'used':88,'free':1}

    def __getattr__(self, item):
        if item[:7] == 'getSize':  # check if an undefined attribute starts with this
            return self.getSize(item[7:])

    def getSize(self, what='total'):
        return self.storage[what.lower()]

print (spaceObj().getSizeTotal)  # 100
Sign up to request clarification or add additional context in comments.

1 Comment

@Thomas "While certainly possible to get an unknown attribute from a class as a property, this is not a pythonic approach" means "although you can make idiosyncratic language syntax, everyone else is going to have a hard time making sense of it". So "works like a charm" is probably more accurately "works like a charm for me this week".
2

You can put the values into the object as properties:

class SpaceObj(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

storage = {'total':100,'used':88,'free':1}
o = SpaceObj(**storage)
print o.total

or

o = SpaceObj(total=100, used=88, free=1)
print o.total

or using __getattr__:

class SpaceObj(object):
    def __init__(self, **kwargs):
        self.storage = kwargs

    def __getattr__(self,name):
        return self.storage[name]

o = SpaceObj(total=100, used=88, free=1)
print o.total

The latter approach takes a bit more code but it's more safe; if you have a method foo and someone create the instance with SpaceObj(foo=1), then the method will be overwritten with the first approach.

Comments

-2
>>> import new
>>> funcstr = "def wat(): print \"wat\";return;"
>>> funcbin = compile(funcstr,'','exec')
>>> ns = {}
>>> exec funcbin in ns
>>> watfunction = new.function(ns["wat"].func_code,globals(),"wat")
>>> globals()["wat"]=watfunction
>>> wat()
wat

1 Comment

How does this help? (or even bear a resemblance to the question?)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.