Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Attribute Abbreviation.
- This file contains a metaclass that can be used to abbreviate attribute names for a class.
- This is a POC made for fun.
- Do yourself a favor and NEVER do this in actual code.
- You've been warned.
- """
- class AbbreviationError(Exception):
- pass
- class Abbreviate(type):
- def __new__(mcs, name, bases, dict_):
- abbreviate = {key for key in dict_ if
- not key.startswith("__") and key.startswith(dict_.get("PREFIX", ""))}
- if any(any(other.startswith(this) and other != this for other in abbreviate) for this in abbreviate):
- raise AbbreviationError("Ambiguous naming prevents proper abbreviation.")
- dict_["ABBREVIATE"] = abbreviate
- def __getattr__(self, name):
- names = [abbr for abbr in self.ABBREVIATE if abbr.startswith(self.PREFIX + name)]
- if len(names) > 1:
- abbrev_names = [abbrev_name[len(self.PREFIX):] for abbrev_name in names]
- raise AttributeError("Abbreviation {!r} matches too many names: {!r}.".format(name, abbrev_names))
- if not names:
- raise AttributeError("Abbreviation {!r} has no matches.".format(name))
- return getattr(self, names[0])
- dict_["__getattr__"] = __getattr__
- return type.__new__(mcs, name, bases, dict_)
- class MyClass(object):
- __metaclass__ = Abbreviate
- PREFIX = "c_"
- def c_print(self, text):
- print text
- def c_add(self, a, b):
- return a + b
- def c_min(self, a, b):
- return min(a, b)
- def c_max(self, a, b):
- return max(a, b)
- if __name__ == '__main__':
- my_class = MyClass()
- my_class.p("Hello, Abbreviation World!") # Calls `my_class.c_print`
- print my_class.a(1, 2) # Calls `my_class.add`
- print my_class.min(0, 1) # Calls `my_class.min`
- print my_class.c_max(1, 2) # Original method names work as well
- try:
- print my_class.m(3, 4) # Ambiguity!
- except AttributeError as ex:
- print ex.message
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement