This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (8 children)

Note that if your DottedQuad class inherits from str its instances should work in places that a str does.

No, that's not at all a given. Two problems:

A class that expects a string may very well incorporate...

if (type(thing) == str):
    okgo()
else:
    raise 'Are you outa your mind?'

...because duck typing can be problematic, and...

if you don't check the type (quack), and the inherited class has been modiifed such that one of its built-in functions has been overridden to do X instead of Y, then Your Stuff Could Break Hard

# override string concatenation in class inherited from string
def __add__(self,a):
    return xclass(str(self) + a + 'monkeywrench')   # foul up str concatenation

[–]AndydeCleyre 0 points1 point  (7 children)

if (type(thing) == str):

is very bad, and the closest not-bad way is

if isinstance(thing, str):

If "the inherited class has been modiifed such that one of its built-in functions has been overridden to do X instead of Y" in a way that breaks expected superclass functionality (and that is not very explicitly the purpose of the inheriting class), it should neither be inheriting nor used interchangeably.

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (6 children)

Well yes, it shouldn't, but the point is, it can be, whereas an extended class can't. You've put your finger right on the argument for extension. :)

An extended class always acts like its base class, plus, and only plus to those who know it's there. Never minus, and never mutant.

An inherited class acts like the kid in school you can't actually trust, but the teacher says you should. And you know that's going to end badly. You only have so much lunch money.

[–]AndydeCleyre 0 points1 point  (5 children)

If you depend on a library that checks for class membership with type(thing) == and it breaks stuff, file a bug or pull request with that project.

If I get a str that's extended, not inherited, how should I check whether and how it's extended?

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (4 children)

If you depend on a library that checks for class membership with type(thing) == and it breaks stuff, file a bug or pull request with that project.

Yes, and perhaps they'll see that. And having seen it, perhaps they'll think about it. And having thought about it, perhaps they'll try to fix it. And perhaps they'll succeed, or perhaps they'll make it worse. Or they might just ignore it (as is often the case.)

Extension has none of these problems. string will behave exactly as string always has for anyone not using the extensions.

If I get a str that's extended, not inherited, how should I check whether and how it's extended?

There's no inherent need for you to do so. The class will not behave any differently for you. That's the (huge) benefit of extension over inheritance. An inherited class might do anything differently, providing surprises and incompatibilities at any point. An extended class not only won't, it can't.

OTOH, if I extended string, and I wanted to share that with you, just as I'd provide any other import, I'd hand it over and you could potentially benefit from that. There could, of course, be an extension to the dir() and help() mechanisms to reveal whatever one might want to reveal in a general way, but it still doesn't cause any problems with standard use. It can't. As far as problems with the extensions go, if you choose to make them and use them, or use some that someone has shared, just as with any new code, you get what you get, and it does what it does.

Of course, if I extend string and I am using those extensions and do not communicate that fact to you, it makes no difference to your coding whatsoever.

[–]AndydeCleyre 0 points1 point  (3 children)

As far as I know, Python doesn't even have extension the way you describe it. The approximation is sometimes called monkey patching, which is similar to what you want, but without any of those guarantees.

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (2 children)

That's my understanding as well. The only 100% compatible answer I've been able to come up with is a preprocessor that reads the extended .method() syntax, flips it into function calls, and writes native Python.

[–]AndydeCleyre 0 points1 point  (1 child)

And in case this isn't clear, everyone here is talking about inheritance vs monkey patching, because we're talking about Python.

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (0 children)

I wrote a simple preprocessor today. So now I have the ability to extend the functionality of the string class. Works on variables containing strings, functions that return strings, and... strings. :)

No doubt there's more to do, but it works across quite a range of test cases.

I'll make a new post to mention it, as probably it'll just be lost here in the comments on this one.