Live data from Hacker News

Understanding Python through its builtins

sadh.life

121–130 of 180 posts

Re: Understanding Python through its builtins

#121
post #43

I am a pretty average Python programmer(5 years teaching, 15 years writing). I still wonder what was the reasoning for allowing creation of local objects with the same name as builtins. Okay it can be nice to redefine pprint as print I suppose. Still how many sum, list, min, max, dict(!) have been erroneously redefined in beginner tutorials and beginner code. From my experience sum and list suffer the most. Sure ther…

   False = None = True
Is probably the most ridiculous thing for a language to support. And yet...

Re: Understanding Python through its builtins

#122
post #2

Nicely written article! - Slightly off topic: I love seeing and reading Python code. Used to see many flaws in the language (things like `.append` changing the object, returning `None` instead of creating a copy and returning that), but after ten years of working with Python I really appreciate its versatility, it‘s ubiquitous availability, the large number of libraries and the community. There‘s nothing I can‘t solv…

And also like a Swiss army knife, it's not particularly great at anything, can be awkward even when functional, and there's always a better tool for any specific job.

Re: Understanding Python through its builtins

#123

Earlier quoted context omitted.

The ! convention is ok but I don't think it's optimal because, in the presence of higher-order functions and related concepts, it's often not clear if a function should be marked as !. For example if I have a map function that applies a function f to a sequence, should I call it map! because I might pass in a function f that mutates the input? If so then it seems like any function that takes a function as input, or a…

map! would mean a function that performs a map in-place on the array by replacing the values. So it would depend on if the callback was encouraged to mutate the array or discouraged from doing so.

Array#map! actually exists in Ruby, too. It mutates the array item by item. Enumerable#each doesn't have a bang, because it doesn't change the enumerable itself, even though it can mutate the objects contained in the enumerable. This is overall consistent -- there's a distinction between mutating the receiving object and mutating objects contained in or referred to by the receiving object.

Re: Understanding Python through its builtins

#124
post #12

Earlier quoted context omitted.

Thank you! Things like `list.append` modifying in-place might feel like a flaw to some, but I think Python is really consistent when it comes to its behaviour. If you ask a person who comes from an object-oriented world, they'll say it only makes sense for a method on an object to modify that object's data directly. There's always ways to do things the other way, for example you can use x = [*x, item] to append and c…

>Python is really consistent when it comes to its behaviour True, though you end up with things like: ' '.join(thelist) Instead of thelist.join(' ') Because of the somewhat aggressive mantra to be consistent.

' '.join() makes more sense to me, and it's more universal too if done right and you accept anything resembling a "sequence" (which python does) and individual objects of the sequence have a sensible str(). And as language maintainer, you only have to maintain one such implementation, not one per collection type.

Javascript, on the other hand, kinda does it worst, at least of the languages I regularly use... .join() is a instance method on Arrays and TypesArrays. But they forgot to add any kind of join for Sets, for example.

    (["a", "b", "c"]).join("")
    "abc" # alright
    (new Set(["a", "b", "c"])).join("")
    Uncaught TypeError: (intermediate value).join is not a function
    ([...new Set(["a", "b", "c"])]).join("")
    "abc" # grmpf, have to materialize it into an array first.
That illustrates the drawback: if you make it a method on the concrete sequence types you got, you better not forget some and make sure the different APIs are consistent, too. If Javascript had a String.join(sep, ) this wouldn't have been an issue.

python isn't alone either, by the way. C# has the static string.Join(...) that accepts "enumerables" (IEnumerable), but no array.Join() or list.Join() or dictionary.Join(). Combined with Linq, especially .Select, that becomes quite handy. It has been plenty of times I did print-debugging by adding a one liner along the lines of

    Console.WriteLine(string.Join("\n", dictionary.Select((key, value) => $"{key} = {value.SomeProperty}")));
I find the C# way of having a string.Join(sep, ...) instead of python's "some string".join(...) nicer to read because it's more obvious.

Re: Understanding Python through its builtins

#125
post #90

Earlier quoted context omitted.

Unfortunatly you often can't use -o because of the 3rd party libs that didnt' get the memo and use assert for error checking. We still have -X dev and sys.flags but it's runtime only.

Care to name any 3rd party libs in particular?

Django Rest Framework.

Re: Understanding Python through its builtins

#126
post #12

Earlier quoted context omitted.

>Python is really consistent when it comes to its behaviour True, though you end up with things like: ' '.join(thelist) Instead of thelist.join(' ') Because of the somewhat aggressive mantra to be consistent.

' '.join() makes more sense to me, and it's more universal too if done right and you accept anything resembling a "sequence" (which python does) and individual objects of the sequence have a sensible str(). And as language maintainer, you only have to maintain one such implementation, not one per collection type. Javascript, on the other hand, kinda does it worst, at least of the languages I regularly use... .join()…

> I find the C# way of having a string.Join(sep, ...) instead of python's "some string".join(...) nicer to read because it's more obvious.

`str.join(sep, ...)` works in Python as well, because `a.f(...)` and `type(a).f(a, ...)` are (almost) equivalent.

Re: Understanding Python through its builtins

#127
post #36

Are there any good books that deal with writing pythonic code? As well as being focused on more intermediate or advanced features like this? If the book is project focused that's a bonus. Performance trade-offs another bonus.

I would recommend "Robust Python" by Patrick Viafore. It teaches you a lot about type annotations (among other thing) and gave me personally a whole new way of looking at the code that I write.

Thanks for the different suggestions, I went with this one. Fluent Python also looked promising but I can't buy the 2nd ed yet.

Re: Understanding Python through its builtins

#128

Are there any good books that deal with writing pythonic code? As well as being focused on more intermediate or advanced features like this? If the book is project focused that's a bonus. Performance trade-offs another bonus.

I can personally recommend Fluent Python (its 2nd edition is about to come out in a couple months) for learning these intermediate/advanced concepts, and Python Cookbook for code examples using many of these features. I don't know any books for projects per-se, maybe HN will know!

To me it looks like a lot of this knowledge is spread out over many different excellent technical blogs like yours. While the content is good, it's hard to get something that resembles a more complete picture compared to just another piece of a big puzzle.

Re: Understanding Python through its builtins

#129
post #98

This is a neat article, but it does have some errors. One subtle point that the post gets wrong: > So where does that come from? The answer is that Python stores everything inside dictionaries associated with each local scope. Which means that every piece of code has its own defined “local scope” which is accessed using locals() inside that code, that contains the values corresponding to each variable name. The dicti…

Oh, I didn't know that about locals!

Yeah, calling float and complex "supertypes" probably wasn't the best idea, but I couldn't think of a better explanation that wouldn't take too long to explain. I'll ponder about that one.

the getattr thing seems like a huge rabbit hole, I'm totally going to look into this. Thank you :)

Post reply on HN