One point has not yet been said. Assume you have a class Vector
and a class Matrix
and both shall be scalable.
With non-member functions, you have to define two scale
functions. One for Vector
and one for Matrix
. But Python is dynamically typed. That means, you must give both functions different names like scale_vector
and scale_matrix
and you always have to explicitly call one of them. If you name them identically, Python does not know which of them you want to call.
This is a significant difference between both options. If you know in advance (statically), what types you have, the solution with different names will work. But if you don't know this in advance, methods are the only way how Python provides 'dynamic dispatching'.
Often 'dynamic dispatching' is exactly what you want, in order to achieve dynamic behavior and a desired level of abstraction. Interestingly classes and objects is the only mechanism how Object Oriented languages (and also Python) provide 'dynamic dispatching'. And there the recommendation of Scott Meyer also fits for Python. It can be read: Use methods only when you really need dynamic dispatching. This is not a question what syntax you like more.
Although you need methods often (or you feel like you need them often), this answer is not a recommendation for the method approach. If you don't plan to use things like inheritance, polymorphism or operators, the non-member solution is better, because it can be implemented immutable (in case you prefer such style), it can be tested easier, it has a lower complexity (as it does not bring all the Object Oriented mechanisms into the game), it is better to read and it is more flexible (as it can be used for all things, that have two components dx
, dy
).
However, as a disclaimer, I must say that in general discussions about encapsulation (e.g. private data) or static typing are not always helpful when working with Python. It is a design decision that these concepts do not exist. It is also a decision of the language designers, that you don't have to define everything in advance. Bringing such concepts into your Python code is sometimes controversial seen, and leads to code, where people might say, this is not pythonic. Not everybody likes the Object Oriented programming style and not always it is appropriate. Python gives you much freedom to use Object Oriented programming only if you want. Not having a non-object oriented mechanism for dynamic dispatching does not mean, that you don't have alternatives.
v.scale(2)
is so much clearer thanscale(v, 2)
. If you look in the standard library, all but the most general functions are kept as members rather than builtins. – Demilitarize