@property def data(self): return f"{self}" Not at a workstation but this should be faster than join() while still using syntax and not builtin functions.
~ Jeremiah On Tue, Dec 20, 2022 at 5:38 PM Christopher Barker <python...@gmail.com> wrote: > As has been said, a builtin *could* be written that would be "friendly to > subclassing", by the definition in this thread. (I'll stay out of the > argument for the moment as to whether that would be better) > > I suspect that the reason str acts like it does is that it was originally > written a LONG time ago, when you couldn't subclass basic built in types at > all. > > Secondarily, it could be a performance tweak -- minimal memory and peak > performance are pretty critical for strings. > > But collections.UserString does exist -- so if you want to subclass, and > performance isn't critical, then use that. Steven A pointed out that > UserStrings are not instances of str though. I think THAT is a bug. And > it's probably that way because with the magic of duck typing, no one cared > -- but with all the static type hinting going on now, that is a bigger > liability than it used to be. Also basue when it was written, you couldn't > subclass str. > > Though I will note that run-time type checking of string is relatively > common compared to other types, due to the whole a-str-is-a-sequence-of-str > issue making the distinction between a sequence of strings and a string > itself is sometimes needed. And str is rarely duck typed. > > If anyone actually has a real need for this I'd post an issue -- it'd be > interesting if the core devs see this as a bug or a feature (well, probably > not feature, but maybe missing feature) > > OK -- I got distracted and tried it out -- it was pretty easy to update > UserString to be a subclass of str. I suspect it isn't done that way now > because it was originally written because you could not subclass str -- so > it stored an internal str instead. > > The really hacky part of my prototype is this: > > # self.data is the original attribute for storing the string internally. > Partly to prevent my having to re-write all the other methods, and partly > because you get recursion if you try to use the methods on self when > overriding them ... > > @property > def data(self): > return "".join(self) > > The "".join is because it was the only way I quickly thought of to make a > native string without invoking the __str__ method and other initialization > machinery. I wonder if there is another way? Certainly there is in C, but > in pure Python? > > Anyway, after I did that and wrote a __new__ -- the rest of it "just > worked". > > def __new__(cls, s): > return super().__new__(cls, s) > > UserString and its subclasses return instances of themselves, and > instances are instances of str. > > Code with a couple asserts in the __main__ block enclosed. > > Enjoy! > > -CHB > > NOTE: VERY minimally tested :-) > > On Tue, Dec 20, 2022 at 4:17 PM Chris Angelico <ros...@gmail.com> wrote: > >> On Wed, 21 Dec 2022 at 09:30, Cameron Simpson <c...@cskk.id.au> wrote: >> > >> > On 19Dec2022 22:45, Chris Angelico <ros...@gmail.com> wrote: >> > >On Mon, 19 Dec 2022 at 22:37, Steven D'Aprano <st...@pearwood.info> >> wrote: >> > >> > But this much (say with a better validator) gets you static type >> checking, >> > >> > syntax highlighting, and inherent documentation of intent. >> > >> >> > >> Any half-way decent static type-checker will immediately fail as >> soon as >> > >> you call a method on this html string, because it will know that the >> > >> method returns a vanilla string, not a html string. >> > > >> > >But what does it even mean to uppercase an HTML string? Unless you >> > >define that operation specifically, the most logical meaning is >> > >"convert it into a plain string, and uppercase that". >> > >> > Yes, this was my thought. I've got a few subclasses of builtin types. >> > They are not painless. >> > >> > For HTML "uppercase" is a kind of ok notion because the tags are case >> > insensitive. >> >> Tag names are, but their attributes might not be, so even that might >> not be safe. >> >> > Notthe case with, say, XML - my personal nagging example is >> > from KML (Google map markup dialect) where IIRC a "ScreenOverlay" and a >> > "screenoverlay" both existing with different semantics. Ugh. >> >> Ugh indeed. Why? Why? Why? >> >> > So indeed, I'd probably _want_ .upper to return a plain string and have >> > special methods to do more targetted things as appropriate. >> > >> >> Agreed. >> >> ChrisA >> _______________________________________________ >> Python-ideas mailing list -- python-ideas@python.org >> To unsubscribe send an email to python-ideas-le...@python.org >> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-ideas@python.org/message/T7FZ3FIA6INMHQIRVZ3ZZJC6UAQQCFOI/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > > > -- > Christopher Barker, PhD (Chris) > > Python Language Consulting > - Teaching > - Scientific Software Development > - Desktop GUI and Web Development > - wxPython, numpy, scipy, Cython > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/I62E7PVP5NN3KYYKFOW5OUKJRQSKNL4T/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/C3VIGTJTNRLUQOMB52OFPZJKYWN54WZN/ Code of Conduct: http://python.org/psf/codeofconduct/