Live data from Hacker News

Using attrs for everything in Python

glyph.twistedmatrix.com

81–90 of 105 posts

Re: Using attrs for everything in Python

#81
post #56

This feels a little bit like Lombok in the Java world. Can anybody with experience with both comment on that? We use Lombok a fair amount within our code to abstract away a lot of the class setup, which has been nice. But as I move more towards the Python world, I'm interested to see how attr fits in.

Lombok is kinda bigger commitment than attrs, because it interfaces with Java compiler internals (last time I used it, it was only possible to compile with sun/oracle jdk).

attrs seems lesser risk IMO, it's just a plain Python library, no other deps.

If you like Lombok, I'd expect you'll love attrs. :)

Re: Using attrs for everything in Python

#82

It feels a bit hampered by "bad" design decisions to me I think its safe to say that the current view of what decorators do is, a) filter things going to functions (so they error, or hit a cache), or b) register a function with another library (e.g. flask path decorator) This library does a lot more than that, so it seems that maybe a metaclass (which exists to mutate the class's creation) would be more appropriate?…

While I view python metaclasses (metaprogramming in general) as a tool of last resort, I have to agree with you. I applaud the attempt - I think it fills an important gap between lists/dicts, namedtuples, and classes. Implemented as a metaclass, I think would be much simpler to get it accepted into core python with fewer backward compatibility issues.

Re: Using attrs for everything in Python

#84
post #35

Earlier quoted context omitted.

Your view of what decorators doesn't seem to reflect the usage I've experienced writing Python professionally over the last 10 years. Decorators take an object and return a object (by convention a callable, although this isn't enforced in the slightest). Maybe they modify a function or method signature, maybe it produces an unrelated object, or maybe one augments the object by adding side effects like caching or logg…

I know how decorators work and you might be missing the point I was making by a fair mile The following don't mutate the mental map of how the function works, its "this function is still what I typed": "add logging" "add tracing" "register functions/objects for various reasons" The following act as a filtering role, the inside isn't "changed", the mental map becomes "This function will operate within this feature in…

Just a data point: MacroPy uses the decorator syntax for "case" classes that produce objects with a similar behavior to "attr.s" generated objects https://github.com/lihaoyi/macropy

Re: Using attrs for everything in Python

#85

  I love Python; it’s been my primary programming language for
  10+ years and despite a number of interesting developments in
  the interim I have no plans to switch to anything else.
"interesting" and "developments" are referred to as haskell and rust respectively in the original post.

"A History of Haskell: Being Lazy with Class" [0] by Paul Hudak et al suggests that it emerged before 1990. See http://haskell.cs.yale.edu/wp-content/uploads/2011/02/histor... the page in the report showing Haskell timeline.

[0] http://haskell.cs.yale.edu/wp-content/uploads/2011/02/histor...

Re: Using attrs for everything in Python

#86
post #6

Earlier quoted context omitted.

http://attrs.readthedocs.io/en/latest/overview.html#on-the-a...

Hello, Hynek! Thanks for attrs, wonderful library! I'd suggest to market the "serious business aliases" more prominently. It's not about aesthetics, but expectations: people like me are immediately puzzled by "attr.ib()", thinking "why ib?". The reason is because after reading a lot of Python code, our brain is already trained to recognize attributes and method names after the dot. Also, it's a reasonable expectation…

Hello, thank you for the rare nice words in this thread!

I got a bit hit by surprise by the submission of this article to HN (it’s like two weeks old now) so it caught me a bit off guard close before a new release and there’s some inconsistency between the GitHub README and the docs on RTD.

The version that’s on PyPI now " rel="nofollow">https://pypi.org/project/attrs/> has it as the first sentence after the first code sample anyone ever sees (and people still complained because the just don’t read :() and the new version " rel="nofollow">https://attrs.readthedocs.io/en/latest/> has a whole section around the example explaining attrs’ scope and ib/s: " rel="nofollow">https://attrs.readthedocs.io/en/latest/overview.html> (the new version also adds and promotes aliases that make more sense but that’s beyond the point).

I feel like I’ve really done my due here and I’ll have to accept that I can’t make everyone happy. :|

Re: Using attrs for everything in Python

#87
post #79
post #73

Earlier quoted context omitted.

...how does it do that? You call attr.asdict() and it searches the attribute values, including inside lists, for more attr objects to convert into dict values? What kinds of values does it search through? The documentation doesn't say, it just gives an example where it works inside a list for some reason.

Why would it need to recurse? The method probably just returns a copy of the instance's __dict__. Maybe updating it with the __slots__ and their values.

It would need to recurse because you want something you can encode in JSON, not a dictionary containing a list containing miscellaneous instances.

We have an example there of an 'attrs' instance, containing a list containing 'attrs' instances, and all of the instances turn into dictionaries.

Re: Using attrs for everything in Python

#89

attrs seems to be all over the place, but I find Schematics ( http://schematics.readthedocs.io/en/latest/ ) much better designed and more powerful.

Yes, Schematics is impressive. Thank you, I added it to my list of Python OOP extensions [1]. I wonder why you need to supply a dictionary to the object instead of keyword pairs.

[1] https://github.com/metaperl/python-oop

Re: Using attrs for everything in Python

#90

Earlier quoted context omitted.

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_bo…

It adds magic. "Explicit is better than implicit" ~ https://en.wikipedia.org/wiki/Zen_of_Python

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.

Post reply on HN