[python] metoda str
Hynek Fabian
hynek.fabian na firma.seznam.cz
Středa Listopad 3 18:31:30 CET 2010
> Ehm, ne, o to my nešlo, šlo mi o přepsání __builtin__ třídy str tak abych
> přepsal chování instancí Stringu.
Tak jak to píšes ale na builtin nesáhneš!
"class str(str)" ti udělá objekt jménem str v LOKÁLNÍM jmenném prostoru,
nikoliv v builtins. V tomto kontextu tvůj lokální jmenný prostor je globální
prostor modulu, ergo v jiných modulech zůstane str nezměněn.
Sáhnout do builtins je možné a prosté:
class MyStr(str): pass
__builtins__.str = MyStr
a je to. Všimni si že nemusíš mást budoucí generace tím, že to pojmenuješ
stejně - konstruktor je sice viditelný pod jménem 'str', ale
__class__.__name__ hotového objektu bude MyStr. Metody, potomci, etc. se bude
odvolávat na objekt MyStr, pouze "uživatelé" jména 'str' potřebují znát nový
objekt pod starým jménem.
Leč, rychlý experiment ukáže, že interpret nekonstruuje řetězcové literály
pomocí __builtins__.str, ale drží někde vlastní referenci na StringType. Řekl
bych, že je to dobře, hrabání se v builtins je nejvetší prasárna nad jakou by
se ještě dalo přivřít oko :-)
Teoreticky bys mohl změnit chování zabudovaných řetězců hrabáním se přímo v
jejich třídě:
"a".__class__.asx = "asx"
Změna přes referenci na třídu se okamžitě projeví u všech existujících
instancí, potomků etc. Předefinováním metody __new__() bys mohl dokonce
dosáhnout aby konstrukce objektu vracela instanci objektu úplně jiného typu,
napříkald MyStr...
Na(ne)štěstí taková konstrukce nefunguje přímo na zabudované objekty,
protože ty nemají vlastní jmenný prostor ale jen neměnitelné sloty.
Běžně to ničemu nevadí, protože jmenný prostor si můžeš opatřit prostě tím,
že podědíš, čímž jsme zpátky u nevrtání se ve střevech interpretru :)
Jiné řešení které mě napadá - projít rekurzivně zadaný jmenný prostor a
instance StringType nenápadně proměnit. Není to sice tolik "automagické", ale
taky mnohem bezpečnější.
Další informace o konferenci Python