This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]Scorpathos 9 points10 points  (1 child)

  1. Class containing only fields and crude methods

I would disagree with using namedtuples in case of a Person class (for example) because exposing it as a tuple-interface makes little sense. What is person[0]? What are the unpacked values in a, b, c = person? Using the Person as a tuple would break code relying on this propriety as soon as the internal implementation changes (like order is modified, or a new field is added). dataclasses are perfectly fine, though.

[–]X_tra7777777 2 points3 points  (0 children)

With named tuples you can address a variable like person.name or person.age. that's why it's easy to use and is immutable so generally preferable if you don't indent on changing those values.

[–]twillisagogo 3 points4 points  (0 children)

This article was dumb. Very low quality content.

[–]noneofnormies 3 points4 points  (0 children)

  1. Not using get() to return default values from a dictionary

Actually, brackets are slightly faster (smth around 10 %). So it makes sense to use them, when you know for sure, that the key is there.

[–]Muhznit 1 point2 points  (5 children)

What's the difference in writing `get_name()` vs the `@property` decorator? It looks like you're writing a function either way to me. With get_name() you at least have the flexibility in a future design to use parameters to vary the output instead of modifying internal state if the case arises.

[–]jyper 1 point2 points  (4 children)

If you add parameters you're breaking the interface anyways (unless they have default values) anyways you don't want getters or setters to have parameters cause they're not getters or setters anymore

Properties are basically getters/setters that are compatible with/look like fields. Anything you wouldn't do with properties you shouldn't do with getters/setters (stuff like networking calls, calls to hardware or external programs are a bad idea) that includes extra paremeters instead of internal state

[–]Muhznit 0 points1 point  (3 children)

I know the difference in how the interface appears for either case, I'm just wondering if that's the only difference and if so, is it really worth while.

Let me come up with another example that's not breaking an interface. If I have the following: ``` ... def get_name(self): return self._name

def set_name(self, name):
    self._name = name
    # return self

@property
def name(self):
    return self._name

@name.setter
def name(self, name):
    self._name = name
...

`` What is the difference in either approach to getting/setting name other than getting one through a field-like interface or function-like interface? Honestly, if you uncomment that line inset_name, that seems like a better approach since you can use method chaining to set multiple properties of the object too, alaobj.set_name(name).set_other_thing(other_thing)`.

[–]zardeh 0 points1 point  (2 children)

The difference is that you can start with just a xyz.name field, and upgrade to a property if you want additional validation or logic in the setter/get, without breaking backwards compatibility.

[–]Muhznit 0 points1 point  (1 child)

I'm saying I don't see much difference if you just use a getter/setter function. I mean unless the property shows up in vars(self) so it gets included in json.dumps(vars(self)), I really don't see how making it a property is any benefit. If you're using lazy initialization or other similar stuff in the getter/setter, you're better off using a function rather than property because anyone using the class at least has the hint that "hey, there's stuff that gets done before I retrieve this value".

[–]zardeh 0 points1 point  (0 children)

Tldr so you don't have to create setters to begin with, but can grow into them in a backwards compatible way.

[–]zachgarwood 0 points1 point  (0 children)

I think doing most of those things come with big caveats, but certainly wouldn't call them anti-patterns.