简体   繁体   中英

How do I dynamically create properties in Python?

Suppose I have a class like this:

class Alphabet(object):
     __init__(self):
         self.__dict = {'a': 1, 'b': 2, ... 'z': 26}

     @property
     def a(self):
         return self.__dict['a']

     @property
     def b(self):
         return self.__dict['b']

     ...

     @property
     def z(self)
         return self.__dict['z']

This would be a long and cumbersome task to define and it seems highly redundant. Is there a way to dynamically create these properties? I know you can dynamically create attributes with the built-in setattr, but I want to have control over read/write/delete access (for this reason I want to use a property). Thanks!

Don't use properties but implement the following methods:

  • __getattr__(self, name)
  • __setattr__(self, name, value)
  • __delattr__(self, name)

See http://docs.python.org/reference/datamodel.html#customizing-attribute-access

Your __getattr__ method could look like this:

def __getattr__(self, name):
    try:
        return self.__dict[name]
    except KeyError:
        msg = "'{0}' object has no attribute '{1}'"
        raise AttributeError(msg.format(type(self).__name__, name))

Don't do that. Just let the consumers of the class at the __dict directly and trust them not to screw it up. Remember, we're all consenting adults here!

Ned Batchelder explains better than I can:


Keep data out of your variable names

The question reminded me of others I've seen on Stack Overflow or in the #python IRC channel:

  • How do I see if a variable exists?
  • How do I use a variable as the name of another variable?
  • How do I use a variable as part of a SQL table name?

The thing all these have in common is trying to bridge the gap between two domains: the data in your program, and the names of data in your program. Any time this happens, it's a clear sign that you need to move up a level in your data modeling. Instead of 26 lists, you need one dictionary. Instead of N tables, you should have one table, with one more column in it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM