Хочется иногда добавить ему функциональности.. Сделать чтоб словари стали как полноценные Java Script объекты например, или же каких то интересных функций дописать для встроенных типов..но.. нельзя.. встроенные типы Python нельзя изменять.. ну кому то может и нельзя, а мне можно ;-) да и вам будет можно, исправлю пожалуй эту несправедливость :-)
Возьмем к примеру всем известный Dict:
data={}
data["kozel"]="vasia"
Мне вот неудобно каждый раз писать много всяких скобочек [][][][[]]]]] """"""", хочу я чтоб как в js было, даже еще проще, вот так:
data={}
data.kozel="vasia"
Что же делать, воспользуемся магическим методом__getattr__
Точнее там __setattr__ в конкретно данном примере, но с ним будет чуть сложнее код, для простоты сосредоточимся на __getattr__
и попробуем изменить поведение Dict:
>>> dict.__getattr__=111
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot set '__getattr__' attribute of immutable type 'dict'
Не вышло.. В том то и беда, нельзя же встроенные типы менять..Нельзя менять dict, list, str, int и все прочее.. И кто это придумал, а главное зачем? Ну да ладно..нельзя так нельзя.. будем писать скобочки дальше Ну уж нет!
Исправим это непонятное ограничение и узнаем как изменить встроенные типы Python
Из командной строки вызываем установку fishook или forbiddenfruit,
кто не знает:
py -m pip install fishook или forbiddenfruit
Ну мне лично fishook больше нравится.
Ну а дальше все просто..Пишем:
from fishhook import hook,hook_cls,hook_property,hook_var,unhook
from hashlib import md5
import re
def listpath(self,key):
self.append(key)
return self
hook(dict,name='__getattr__',func=lambda self,key: self[key]) # data.kozel => "kolya"
hook(list,name='__getattr__',func=listpath)# [].xxx.yyy => ['xxx','yyy']
hook(str,name='__getattr__',func=lambda self,key: key) # ''.xxx => 'xxx'
hook(str,name='int',func=lambda self,base=10:int(self,base)) #'555'.int() => 555
hook_property(str,'md5', lambda self:md5(self.encode()).hexdigest() ) # 'qwerty'.md5 => md5 hash of str
hook_property(str,'md5int', lambda self:int(self.md5,16)) # int md5 hash
hook_property(str,'isint', lambda self: re.fullmatch('(-|)[0-9]+',self) ) #'-321'.isint => True || 'asd'.isint => False
hook(str,name='delchars', func=lambda s,chars: ''.join([c for c in list(s) if c not in chars]) ) # 'qw1er2ty3'.delchars('123') => 'qwerty'
hook(str,name='re', func = lambda self,regexp: re.findall(regexp,self) ) # 'hello world 54321'.re('[A-z]+') => ['hello','world']
hook_property(str,'ruswords', lambda self: self.re('[А-я-]+') ) # 'привет мир Python'.ruswords => ['привет','мир']
hook_property(str,'engwords', lambda self: re.findall('[A-z-]+',self) ) # 'привет мир Python'.engwords => ['python']
Ну вот и все! Можно извращаться над встроенными типами питона как угодно :-) В комментариях к коду достаточно подробно описано что делает каждый хук, вот и вроде удобнее стало, не так ли? :-) Если есть идеи новых извращений, всяческих хуков - пишите :-)