3 ms·
A Python style preference I'm rapidly deriving is as soon as there's more than two arguments to a function, especially when you're mixing in args with defaults,
by EdwardDiego 4y ago
A Python style preference I'm rapidly deriving is as soon as there's more than two arguments to a function, especially when you're mixing in args with defaults, I'm thinking about enforcing kwarg syntax only at a language level. Just to force the code to be more readable at the call site.
E.g.,
def bla(self, a, b, c=2, d=True):
self.bla("x", "x", 3)
Ain't no way in hell I'm wanting those arguments to be used positionally by callers. They're getting THE KWARG IS MANDATORY STAR.
def bla(self, *, a, b, c=2, d=True):
self.bla(a="x", b="x", c=3)
It adds more vertical to your code when you have meaningful argument names, but it makes it a lot clearer what is what, and the language enforces what just used to be a good style.
It's especially important when Python's mocking comes into play.
In languages like Java, you can determine what is what based on types... (with static imports for both)
X x = new X(mock(Y.class));
Makes it far clearer what X is working with than
x: X = X(MagicMock())
- vorticalbox 4y agoKwargs is a feature I miss now I work in a typescript/nodejs code base. Sure you can objects bits it not the same.
- goodoldneon 4y agoIn TS, an object is close to being kwargs. My main issue is that it’s much more verbose since you separately write the destructure and type, so you have to write the args twice. But one nice thing is that consumption is less verbose than Python. In Python you write “greet(name=name)” but in TS you write “greet({name})”
- Kwpolska 4y agoYour mock example could be improved (in both languages) by defining a variable for the Y mock. You probably want a variable anyway, so you can define the mock’s behaviour or verify it was used correctly. Also, Java’s a pretty bad example, as it lacks default arguments and named arguments, leading to the ugly and verbose builder pattern. (Side note, why didn’t Java add them yet, after so many years of their usefulness being seen in Scala, Kotlin, C# to name a few related languages?)
- joshuamorton 4y agoWhile it's not required, there's nothing stopping you from doing any of: x: X = X(MagicMock(Y)) x: X = X(MagicMock(Y(...))) x: X = X(MagicMock(spec=Y)) which all make it fairly clear that the Mock is of Y. (or better yet, use fakes instead of mocks)
- EdwardDiego 4y agoYeah it's the fact that it's not required that makes me insert the *.