This is a subclass of a standard str object that adds methods for applying color, and video attributes to text.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | import re
class Scale(str):
def __len__(self):
'''
This ensures that you will always get the actual length of the string,
minus the extended characters. Which is of course important, when you
are calculating output field sizes. Requires the re module.
'''
tmp = self[:]
cnt = 0
for i in re.sub('\\x1b[\[0-9;]*m', '', tmp):
cnt += 1
return(cnt)
def __getattr__(self, method):
'''
This is essentially an implimentation of Ruby's .method_missing
that shortens the code dramatically, and allows for simply extending
to support other escape codes. As a note, the modifier methods like
.bold() and .underline() and such, need to come before the color
methods. The color should always be the last modifier.
'''
method_map = {
'black': {'color': True, 'value': 30, 'mode': 'm'},
'red': {'color': True, 'value': 31, 'mode': 'm'},
'green': {'color': True, 'value': 32, 'mode': 'm'},
'yellow': {'color': True, 'value': 33, 'mode': 'm'},
'blue': {'color': True, 'value': 34, 'mode': 'm'},
'purple': {'color': True, 'value': 35, 'mode': 'm'},
'cyan': {'color': True, 'value': 36, 'mode': 'm'},
'white': {'color': True, 'value': 37, 'mode': 'm'},
'clean': {'color': False, 'value': 0, 'mode': 'm'},
'bold': {'color': False, 'value': 1, 'mode': 'm'},
'underline': {'color': False, 'value': 4, 'mode': 'm'},
'blink': {'color': False, 'value': 5, 'mode': 'm'},
'reverse': {'color': False, 'value': 7, 'mode': 'm'},
'conceal': {'color': False, 'value': 8, 'mode': 'm'},
}
def get(self, **kwargs):
if method_map[method]['color']:
reset='[0m'
else:
reset=''
return(
Scale('%s[%s%s%s%s' % (
reset,
method_map[method]['value'],
method_map[method]['mode'],
self,
reset
)
))
if method in method_map:
return get.__get__(self)
else:
raise(AttributeError, method)
|
wow, I'm an idiot.
Good to know the method
I am learning Python 3 and found your code very instructive. However I had a hard time understanding this line:
since I did not understand what the __get__ method of a function did.
I find that it is shorter and clearer to define attributes of the class instead of functions, as such:
This works in a similar way, but you use:
instead of
However, as I mentioned I am just learning Python 3, so I may be missing something here.