Live data from Hacker News

Using attrs for everything in Python

glyph.twistedmatrix.com

71–80 of 105 posts

Re: Using attrs for everything in Python

#72

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

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

#73
post #67
post #30

"Another place you probably should be defining an object is when you have a bag of related data that needs its relationships, invariants, and behavior explained. Python makes it soooo easy to just define a tuple or a list." Yes, and defining a tuple or a list is often better than a small object because of Python's problems with serializing (pickling) objects. If you're doing anything with data, anything functional, a…

None of this is a problem with attrs. Serialize however you like. >>> import attr >>> >>> @attr.s ... class Thing(object): ... a = attr.ib() ... b = attr.ib() ... ... >>> @attr.s ... class Many(object): ... things = attr.ib() ... ... >>> many = Many([Thing(1, 2), Thing(3, 4)]) >>> many Many(things=[Thing(a=1, b=2), Thing(a=3, b=4)]) >>> attr.asdict(many) {'things': [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]} >>> import pic…

...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.

Re: Using attrs for everything in Python

#74
While I do see the usefulness for the specific example, and while it does seem to reduce boilerplate which is really nice, how useful it is outside of the Point3D example? For example, how often do you actually gt/lt comparisons between classes, or equate classes when they're not mathematical constructs like this? And if you add an attribute that shouldn't be used in repr or comparison, you have to explicitly say that in the attribute declaration, meaning it's would be much less clear what's going on down the road -- as in it won't be apparent how the comparison works or why this is being printed the way it is -- which I don't like in a language like Python. It almost seems like you're trading language level boilerplate for this library's boilerplate, and while it may be less with this library it obfuscates what's going on at the expense of more explicit code.

I can kind of understand something like this in Ruby, as it kind of encourages this (and it also has nicer class string-ification by default), but in Python I'd rather have all of my logic be explicitly stated out at the expense of less boilerplate. Also how often do you really need to overwrite those gt/lt methods in production code? If I saw that, rather than an explicit e.g. `.gt` method, I'd consider that a code smell.

Re: Using attrs for everything in Python

#75
post #31

Earlier quoted context omitted.

Agreed. From the post, it seems to me like another (IMO better) alternative to this awkward attr-specific convention and syntax etc would be to create a factory function for dynamic class definition, in a similar vein to namedtuples. This is functionally similar to the metaclass route, and to be honest I'm not sure what the tradeoffs would be. Either way, I think metaprogramming is a much better approach than attrs i…

There is one: >>> C2 = attr.make_class("C2", ["a", "b"]) >>> C2("foo", "bar") C2(a='foo', b='bar')

SimpleNamespace is good for that. https://docs.python.org/3/library/types.html#types.SimpleNam...

Re: Using attrs for everything in Python

#76

Earlier quoted context omitted.

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

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.

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

#77
post #28
post #8

Earlier quoted context omitted.

you can just do class B: def __init__(self, a, b, c): self.__dict__.update(locals())

That makes B.self a field too, which you probably don't want.

Especially because that creates a circular reference and annoys the garbage collector.

Re: Using attrs for everything in Python

#78
post #30

"Another place you probably should be defining an object is when you have a bag of related data that needs its relationships, invariants, and behavior explained. Python makes it soooo easy to just define a tuple or a list." Yes, and defining a tuple or a list is often better than a small object because of Python's problems with serializing (pickling) objects. If you're doing anything with data, anything functional, a…

That's a problem with pickle, not namedtuple. I assume you're complaining about not being able to pickle an instance of a locally defined class?

Re: Using attrs for everything in Python

#79
post #73
post #67

Earlier quoted context omitted.

None of this is a problem with attrs. Serialize however you like. >>> import attr >>> >>> @attr.s ... class Thing(object): ... a = attr.ib() ... b = attr.ib() ... ... >>> @attr.s ... class Many(object): ... things = attr.ib() ... ... >>> many = Many([Thing(1, 2), Thing(3, 4)]) >>> many Many(things=[Thing(a=1, b=2), Thing(a=3, b=4)]) >>> attr.asdict(many) {'things': [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]} >>> import pic…

...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.

Re: Using attrs for everything in Python

#80
post #65
post #63

Earlier quoted context omitted.

Assigning a variable to a destination declared to be an incompatible type should produce an error at compile time if possible, and at at run time otherwise. That's what type declarations are all about.

I think you misunderstand. Here's an example: ``` foos = [Foo(a=0), Foo(a=1)] f0 = foos[0] foos[0] = Foo(a=2) print(f0.a) # 0 print(foos[0].a) # 2 ``` `foos` is a list of type `Foo`, but it still can't be safely made into a dense list (at least not naively).

You are right. Array elements need to have value semantics to do complete unboxing. But for NumPy-like use cases, they do.

It should be noted that PyPy already does unboxing Animats suggested, without any type annotation. At least for 4 years. It is not theoretical. https://morepypy.blogspot.com/2011/10/more-compact-lists-wit...

Post reply on HN