News for hackers. Stuff that matters.
Re:Using attrs for everything in Python by mkolodny on Thursday August 25, 2016 @12:33PM (#12360374)
While the conciseness of attrs is nice, it's not very readable.

This:

    class Point3D(object):
        def __init__(self, x, y, z):
            self.x = x
            self.y = y
            self.z = z
...is much easier to read than this:

    import attr
    @attr.s
    class Point3D(object):
        x = attr.ib()
        y = attr.ib()
        z = attr.ib()
Readability is what I love about Python. I don't think the conciseness of attrs is worth the loss in readability.
Re:Using attrs for everything in Python by dlbucci on Thursday August 25, 2016 @12:48PM (#12360482)
According to the article, that's not really a fair comparison. The first example would need functools and at least 3 more methods to get to the same functionality of the latter example, at which point I think the former is less readable.

That said, I'm not a big fan of wrapping classes, or this library's weirdly-but-concisely-named functions. I guess I'll have to give this a try the next time I'm writing Python to see if it's that much of a boost.

Re:Using attrs for everything in Python by crdoconnor on Thursday August 25, 2016 @07:27PM (#12363270)
Those 3 methods aren't at all necessary for most objects you'll create and use.
Re:Using attrs for everything in Python by mixmastamyk on Thursday August 25, 2016 @12:53PM (#12360526)
Also, read the post and looked over the docs, and don't see any explanation of what `.s` and `.ib` is supposed to mean (though I can figure out from context). Does anyone know what the letters stand for? Struct and instance b…???
Re:Using attrs for everything in Python by Myrmornis on Thursday August 25, 2016 @01:04PM (#12360613)
> They are a concise and highly readable way to write attrs and attrib with an explicit namespace.

> For those who can’t swallow that API at all, attrs comes with serious business aliases: attr.attrs and attr.attrib.

I'm definitely in the can't swallow camp. There's no precedent for using attribute namespaces to name things with half the name on one side and half the name on the other side, so who the hell does this project think it is to start doing it? :) Seriously though I'm pretty sure I hate it.

And I'm having trouble liking the "proper" names. So we use a class decorator "@attrs" to declare "this class is going to use class attributes to declare available instance attributes slots, a bit like django or schematics fields". Maybe it would have been better to call it "@attrs.model" since it is essentially a model definition in the terminology of other data modeling projects?

Re:Using attrs for everything in Python by gknoy on Thursday August 25, 2016 @05:20PM (#12362601)
If you use `import ... as ...`, you can rename them to nicer names (full gist at [0]):

    from attr import (
        s as AttributedModel,
        ib as attribute,
    )
    
    @AttributedModel
    class Bar(object):
        x = attribute()
        y = attribute()


0: https://gist.github.com/gknoy/6e884fce3edda08a1566823fec37ba...
Re:Using attrs for everything in Python by jfb on Thursday August 25, 2016 @12:56PM (#12360555)
attr.s = "attrs" = plural of "attr"

attr.ib = "attirb" = alternate spelling of "attr"

It's too cute by half.

Re:Using attrs for everything in Python by ctoth on Thursday August 25, 2016 @07:04PM (#12363166)
It's awesome that Glyph wrote this article, but so many people are getting stuck on the default names here (me too, I don't like them so very much) that it's really detracting from the commentariet.

From the Attrs documentation:

(If you don’t like the playful attr.s and attr.ib, you can also use their no-nonsense aliases attr.attributes and attr.attr).

Re:Using attrs for everything in Python by hynek on Thursday August 25, 2016 @12:54PM (#12360537)
Re:Using attrs for everything in Python by rainy-day on Thursday August 25, 2016 @06:33PM (#12363014)
As I think others noted, the attr version does alot more: it adds representation and easily adds compare methods as shown in OP.

Aside from that, this is not a fair comparison because attr names can, and mostly should be, longer, and there can be more of them, e.g.:

    class SomeClass(object):
        def __init__(self, myattr1, some_val, a_bool,
                     my_other_attr):
            self.myattr1 = myattr1
            self.some_val = some_val
            self.a_bool = a_bool
            self.my_other_attr = my_other_attr
And of course they'll need to go into __str__ method as well.
Re:Using attrs for everything in Python by carapace on Thursday August 25, 2016 @06:40PM (#12363051)
It adds magic.

"Explicit is better than implicit"

~https://en.wikipedia.org/wiki/Zen_of_Python

Re:Using attrs for everything in Python by RubyPinch on Thursday August 25, 2016 @09:28PM (#12363759)
I feel like a person should be able to back their opinion up (for a specific case, not in general), instead of just mindlessly quoting a line from a bible.
Re:Using attrs for everything in Python by njbooher on Thursday August 25, 2016 @10:20PM (#12363916)
The magic in programming war is eternal and which side you're on ought to just be added to the Myers-Briggs test.
Re:Using attrs for everything in Python by carapace on Friday August 26, 2016 @02:29PM (#12368246)
See comment in this post in reply to Glyph. (And don't be a jerk.)
Re:Using attrs for everything in Python by dr_zoidberg on Friday August 26, 2016 @09:37AM (#12366102)
Then let's get rid of the with semantics too, because they add magic.

Compare:

    with open("file.txt") as somefile:
        for line in somefile:
            print line
To the more explicit and clear:

    somefile = open("file.txt")
    line = somefile.readline()
    while line:
        print line
        line = somefile.readline()
    somefile.close()
But I'm still using some magic, I should be more explicit:

    def explicit_readline(fd):
        buff = []
        char = fd.read(1)
        while char != "\n" and char != "":
            buff.append(char)
        return "".join(buff)
    somefile = open("file.txt", "rb")  # just to be sure now
    line = explicit_readline(somefile)
    while line != "":  # to be more explicit, of course
        print line
        line = explicit_readline(somefile)
    somefile.close()
And we could go on like this to replace open with the os module file-descriptor functions, and print with sys.stdout/stderr (because more explicit, right?). But even without getting there, it should be obvious that:

* The "explicit" verison no longer behaves as the original one, because, for example, explicit_readline only handles well the NIX newline character. If I want to provide the same functionality as file.readline() I should add a lot more code.

I've reinvented the wheel for no good reason, and readability has suffered. It may also leave a lingering question in the mind of a read "why did he do that? is there some edge case that wasn't well documented anywhere and he bumped into?".

* I've seen more contrived code do a version of this "more explicit" programming style, to the point of having statements like:

    def f1(number):
        number = int(number)
        return number & 0xff00  # or plug the number parameter in an equation, etc
* ... (not a verbatim example, but along those lines). And that code is redundant and it will fail anyway if another thing other than an int/long/float is passed. It would be certainly saner to have an assert, or simply specify in the docs that said function expects a number (which is implied in the args too).

My point was the "Explicit is better than implicit" means "be clear of your intent". And if I see someone using the attr module (which comes with the standard library), and I'm not familiar with it, I'll read into it. And for it's use case, I think it's clear enough in what it does, and how it should be used.

Re:Using attrs for everything in Python by carapace on Friday August 26, 2016 @02:41PM (#12368324)
Oh c'mon Zoidberg, that's a strawman argument. "with" is a Python keyword and the statement syntax is in the grammar. I would expect any working Python developer to know what it is, and even understand how to write a context manager.

...wait wat? It's in the Standard Library? No, I just checked and it's not. Too bad, if it was "blessed" by inclusion in the library I would totally withdraw my objection on that grounds.

You had me going for a second there. ;-)

You make my point for me though when you say that you'd have to read up on it when you first encountered it. That's exactly my point:

The trade off is between one application of attr to the code base to save N time/effort for the current developer one time, versus every bit of lost time/effort of future devs taken to understand the attr package.

It's cute, but it's an in-joke. Don't put in-jokes in code you want other people to use, otherwise they have to "get the joke" before they can work with it. That's what I'm on about.

Re:Using attrs for everything in Python by dr_zoidberg on Saturday August 27, 2016 @12:41AM (#12371026)
Weird, in Windows (Python 2.7.10) I have it without having ever installed it. Even pip uninstall didn't get it (just to make sure it wasn't installed from a dependency) but I can still import it.

On my Linux machine (Python 2.7.6) I can't import it without a previous install from pip install (that's reasonable).

Can't track down much about why this happens because googling "python attr" brings results about hasattr, getattr, etc, but few about the attr module.

Re:Using attrs for everything in Python by glyph on Saturday August 27, 2016 @03:31PM (#12373795)
It's not an "in-joke". It follows conventions set by the Python language:

- "def" instead of "define"

- "cls" instead of "Class"

- "sys" instead of "system"

- "os" instead of "operating_system_facilities"

- "ntpath" instead of "windows_path_names"

- "abc" instead of "abstract_base_classes"

Python aggressively abbreviates almost everything in common use. If it were in the stdlib, perhaps it would be the built-in names "attrs" and "attrib" rather than having dots in them, but the names would indubitably still be very short.

Re:Using attrs for everything in Python by carapace on Saturday August 27, 2016 @06:13PM (#12374403)
It's an "in-joke" in the sense that it doesn't make sense until you get the joke. There are people in this post discussion asking "What means .s and .ib?" It's not obvious to everyone.
Re:Using attrs for everything in Python by crdoconnor on Friday August 26, 2016 @03:45PM (#12368817)
>Then let's get rid of the with semantics too, because they add magic.

With just runs the enter and exit method of a context manager. Nothing magical about it.

>My point was the "Explicit is better than implicit" means "be clear of your intent". And if I see someone using the attr module (which comes with the standard library), and I'm not familiar with it, I'll read into it.

You don't have to read into 'with' to make an intelligent guess at what the code does. It's meaningful even if you've never heard of context managers.

Unlike this.

Re:Using attrs for everything in Python by scott_s on Thursday August 25, 2016 @02:30PM (#12361263)
I find the @attr example more readable.

I've been using Python for a while, but it's not my main development language. I mainly use it for scripting experiments, processing data and generating graphs. I generally avoid defining classes as much as possible, and use namedtuple whenever appropriate.