Hacker News new | past | comments | ask | show | jobs | submit login

Explicit is better than implicit. If you want to call base64.b64encode on a piece of data, do that.



Just that codecs supported incremental operations and base64.b64encode did not. Handling HTTP transfer encoding in python 2 was a matter of two lines and worked on arbitrary stream data. In Python 3 that's now ~50 lines of code with different behavior for each transfer encoding and not all of them support stream processing or have the same interface.


It's less convenient, it's a different API for every type of transformation, and the change has made code demonstrably worse.

Further, the use of encode/decode is explicit. The only thing that was implicit was the automatic transformation of string -> unicode when people mistakenly used unicode codecs on string objects, or the reverse for string codecs on unicode objects. The proper answer to both of these is to just not do automatic type conversion... which is what was done in Python 3.

So actually, had we left all of the codec machinery intact, those codec errors described by Armin wouldn't ever occur again! Instead, you'd get a TypeError caused by passing the wrong type of object to the underlying encoder/decoder.


The API is nice, but it is difficult to maintain. To get encoders/decoders into the string class in the first place, you have to maintain a global registry. (I suppose you could pass them all to the constructor of the string object, but nobody's going to do that.) The global codec registry leads to naming conflicts. If you import a module that globally adds a "foo" encoder, then you import another module that globally adds a "foo" encoder, now what? Both modules break because of their dependency on the global name "foo". Because of the details of the codec.register implementation, you can't even catch the conflict at registration time and refuse to load the second module, you simply have to wait until your program returns subtly-incorrect results.

Compare this to the scheme where you import codec modules explicitly and just call their functions. Your imports are lexically-scoped, and if you happen to need two encoders that use the same name, you can just alias one of them at import time. This strategy can't introduce unexpected errors as your program grows larger, because the side effects are constrained to one module. It either works now and will always work, or doesn't work and fails quickly while you are developing.

Ultimately, people use Python because they want a bit of discipline in their lightweight language. This isn't Javascript or PHP, after all :)


Codec registration has never been an issue. Let me repeat that with some emphasis, because it's an important point. Codec registration has NEVER BEEN AN ISSUE.

And global registries are not inherently a bad thing. If you were to say "I don't want a json/pickle/messagepack decoder built into the codecs module by default", I would agree - because it's not a string/unicide <-> string/unicode transformation. But it wouldn't bother me for someone to add that support in their stuff because data.decode('json') is terribly convenient. Arguably better than peppering your code with the following (or loading it in a shared space, or injecting it into __builtins__, ...)

try: import simplejson as json

except ImportError: import json

But ultimately we are adults. If you would prefer to import a cluster of modules just to convert your strings to hex or compress your string with zlib, you are free to do so. It's just unfortunate that due to misunderstandings about the fundamental underlying problem (TypeErrors), functionality was removed.


There should be one (and preferably only one) obvious way to do it. *.encode(x) was pretty obvious. The new stuff is not.


Ultimately, adding random methods to classes introduces many subtle side effects. (See my reply to a sibling comment above.)

There's noting intrinsically obvious about making the string class responsible for encoding and decoding, other than the fact that help("") mentions the existence of that method. Most other useful utilities that operate on strings are separate classes or modules; re, for example.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: