I just read through this article now. It's hard for me to judge because these certainly aren't new concepts for me, but I don't think it's a good intro. The classes are very minimal but still have...
I just read through this article now. It's hard for me to judge because these certainly aren't new concepts for me, but I don't think it's a good intro. The classes are very minimal but still have design issues, and some of the Python isn't idiomatic at all. For example, you should never write if self.eaten == False:, it should just be if not self.eaten:.
It also starts out explaining the absolute basics of what a class is, and then after a couple of extremely basic examples, suddenly jumps to advanced topics like multiple inheritance, method resolution order, and composition, which I don't think have any place in a post targeted at beginners. You're very unlikely to need any of those until you start getting into some pretty complex programs, and it's likely to be overwhelming. It was fairly confusing even to me, and I already know how all of these concepts work.
I think a lot of programmers who learn multiple programming languages learn Python as one of those languages, but they never bother to learn Pythonic idioms. I think that’s excusable in some cases...
For example, you should never write if self.eaten == False:, it should just be if not self.eaten:.
I think a lot of programmers who learn multiple programming languages learn Python as one of those languages, but they never bother to learn Pythonic idioms. I think that’s excusable in some cases where Python idioms are not like any other languages, but stuff like boolean comparison is pretty basic. I work with a lot of Java devs and it’s pretty awkward to wade through their Python. I don’t want to say the flexibility of Python is a bad thing, but it allows you to go way off the rails if you’re either a beginner or haven’t spent enough time studying the language/standard library or important PEPs.
I don't think you can really blame Python for it. It's not like the language can (or should) prevent you from writing if something == False, it's perfectly valid code and it does work exactly the...
I don't think you can really blame Python for it. It's not like the language can (or should) prevent you from writing if something == False, it's perfectly valid code and it does work exactly the same as writing it idiomatically, so there's not really anything truly wrong with it.
That's just the nature of language idioms, you have to learn the "culture" of that language to see how other people using it will expect you to do certain things. I think a good way to learn is to work on a project with more-experienced devs that can review your code and point out when you do things non-idiomatically, and you can also look through the code they're writing to see how they do things.
Yeah, but it’s a little awkward when Pythonistas laud the Python language design principles such as those in "The Zen of Python" like: The unary not operator is probably very confusing, for...
Yeah, but it’s a little awkward when Pythonistas laud the Python language design principles such as those in "The Zen of Python" like:
There should be one-- and preferably only one --obvious way to do it.
The unary not operator is probably very confusing, for instance:
It is a bit confusing laid out like that, but there is at least a fairly simple underlying principle at work - True and False are guaranteed to behave like 1 and 0 (at least in Python 3).
Truthiness coercion wasn’t even the point I was trying to make, but it can also be confusing. Maybe I can try to make my point about Python’s not more concisely: In [1]: 1 is 1 Out[1]: True In...
Truthiness coercion wasn’t even the point I was trying to make, but it can also be confusing. Maybe I can try to make my point about Python’s not more concisely:
Idioms are inherently part of a language, just like natural language. Just because you know English doesn’t mean you know all English idioms (esp. uncommon, archaic ones). E.g., Python’s dunder...
Idioms are inherently part of a language, just like natural language. Just because you know English doesn’t mean you know all English idioms (esp. uncommon, archaic ones). E.g., Python’s dunder methods: I see a lot of beginner Python code from devs coming from other languages where classes have custom show, length, etc. methods when they should be using __repr__, __len__ etc.
I find OOP in Python terse, increasing cognitive load. But it's beautiful and pleasant. OOP in Java, on the other hand, is ridiculously verbose, but also unambiguous by design. I'm just a...
I find OOP in Python terse, increasing cognitive load. But it's beautiful and pleasant. OOP in Java, on the other hand, is ridiculously verbose, but also unambiguous by design. I'm just a beginner, but I suppose there's some middle ground to achieve here.
What are you trying to achieve? By declaring types you will inherently be verbose. You could, for example only give functions input & output parameters a type, which I already a big step in...
What are you trying to achieve? By declaring types you will inherently be verbose. You could, for example only give functions input & output parameters a type, which I already a big step in understanding the code
I have trouble with short-term memory (ADHD), and one of my main issues with OOP in Python is simply forgetting what things are and do, even on small programs. Looking-up essential stuff every 5...
I have trouble with short-term memory (ADHD), and one of my main issues with OOP in Python is simply forgetting what things are and do, even on small programs. Looking-up essential stuff every 5 to 10 seconds break my "flow", requiring constant "cognitive reboots". I figured a bit more verbosity might help, but, since I'm a beginner, I tend to mimic whatever book, documentation or tutorial I'm following just because I don't know any better.
Your suggestions seem really good, could you maybe point to some layman-friendly articles or documentation that goes over these features?
I think for the very basic thing, this should suffice: https://docs.python.org/3/library/typing.html just let me know if you have trouble understanding anything in there. I think this example...
just let me know if you have trouble understanding anything in there.
I think this example covers the basic knowledge needed:
defgreeting(name:str)->str:return'Hello '+name
so you can type parameters (here the parameter is name) by using a colon, and you let the user /interpreter know that the return value is a string as well. Denoted by the arrow.
here's a list of types: https://realpython.com/python-data-types/
I guess the most important are str, float and int. Of course this will get much more complex with time haha
You can run mypy (or some other checkers) against code with type annotations and it will tell you if you have any type errors. I think some IDEs can also use them to do a better job of suggesting...
You can run mypy (or some other checkers) against code with type annotations and it will tell you if you have any type errors. I think some IDEs can also use them to do a better job of suggesting variables/methods based on what makes sense with the types.
For example if I copy @ali's function and accidentally call it with a number instead of a string:
test.py:4: error: Argument 1 to "greeting" has incompatible type "int"; expected "str"
That's a really contrived example that wouldn't really matter because your program would crash as soon as you tried to run it anyway, but it can help a lot in more complicated cases. For example maybe you have a function called get_name() that almost always returns a string, but can occasionally return None if something goes wrong. If you do something like this:
name=get_name()print(greeting(name))
That looks totally reasonable and your program will work as long as get_name() does return a string, but it has the potential to crash in those rare cases where it returns None. mypy will catch that and tell you about the potential error, because it knows get_name() doesn't always return a string but greeting() always needs one, so there's a mismatch.
here's an interesting read on that: https://pawelmhm.github.io/python/static/typing/type/annotations/2016/01/23/typing-python3.html In Python your program does not crash when running into invalid...
In Python your program does not crash when running into invalid types, as it would in other languages, so without additional tools, the readability is the only advantage (as far as I know). The article mentions a library (mypy) which would precheck the types and tell you whether there is a type error. In languages like Java this is part of the design choice. In Python it is not
Personally I dislike OOP and avoid it when I can, but I’m glad that Python is flexible enough to support it. I don’t like some of the conventions and the syntax, but it’s OK. If possible, I try to...
Personally I dislike OOP and avoid it when I can, but I’m glad that Python is flexible enough to support it. I don’t like some of the conventions and the syntax, but it’s OK. If possible, I try to use collection types from the collections module in the standard library such as namedtuple. Generally when I encounter very stateful Python APIs, they are hard to work with (such as Selenium’s Python driver). I find functional and imperative Python more my style.
Which strand of functional programming you use the most? I’m learning OOP with Java at uni. It feels like killing mosquitoes with a bazooka. I suppose it makes sense for large complex...
Which strand of functional programming you use the most?
I’m learning OOP with Java at uni. It feels like killing mosquitoes with a bazooka. I suppose it makes sense for large complex applications, but I can’t tell right now. But I don’t like it. It’s bureaucratic coding.
It’s not possible to write totally side-effect free code in Python, but generally, I try to not use any mutable data types, and if I do, I try to write functions to encapsulate any mutation. I...
It’s not possible to write totally side-effect free code in Python, but generally, I try to not use any mutable data types, and if I do, I try to write functions to encapsulate any mutation. I like to pass around functions as first-class objects when it makes sense, such as making use of the key argument for sort, min, and max:
Here’s an example of a program I wrote to compute Krippendorff’s alpha coefficient, a measure of inter-annotator reliability. I only made one class in that program, and that class is just a convenient namespace for consuming code to inject new delta functions. I actually don’t like my implementation there, and I suppose I could break it out into a separate module, but point was really just that I didn’t want to pollute the global namespace with lots of function names. I could also use a decorator (I did the decorator thing in this program with the Format class). I’m not totally happy with either solution, but they work.
E.g.,
In[1]:fromkrippendorffimportDifferenceIn[2]:classMyDifference(Difference):...:deffoo(self,v1,v2,*args):# v1 and v2 always differ by 1.0...:return1.0...:defbar(self,v1,v2,*args):# v1 and v2 never differ...:return0.0...:In[4]:diff=MyDifference(float)In[5]:diff.nominal(None,None)Out[5]:0.0In[6]:diff.foo(None,None)Out[6]:1.0In[7]:diff.bar(None,None)Out[7]:0.0In[11]:Difference(float,method='ordinal')._delta(1.0,3.0)Out[11]:16.0
operator.methodcaller is really neat to allow stuff like Difference._delta which is very convenient for allowing a command line driver to specify which delta method to use by interpreting a string argument as a class method name. If you are interested in writing functional Python, I highly recommend checking out the operator, functools, and itertools modules from the standard library.
I just read through this article now. It's hard for me to judge because these certainly aren't new concepts for me, but I don't think it's a good intro. The classes are very minimal but still have design issues, and some of the Python isn't idiomatic at all. For example, you should never write
if self.eaten == False:
, it should just beif not self.eaten:
.It also starts out explaining the absolute basics of what a class is, and then after a couple of extremely basic examples, suddenly jumps to advanced topics like multiple inheritance, method resolution order, and composition, which I don't think have any place in a post targeted at beginners. You're very unlikely to need any of those until you start getting into some pretty complex programs, and it's likely to be overwhelming. It was fairly confusing even to me, and I already know how all of these concepts work.
I think a lot of programmers who learn multiple programming languages learn Python as one of those languages, but they never bother to learn Pythonic idioms. I think that’s excusable in some cases where Python idioms are not like any other languages, but stuff like boolean comparison is pretty basic. I work with a lot of Java devs and it’s pretty awkward to wade through their Python. I don’t want to say the flexibility of Python is a bad thing, but it allows you to go way off the rails if you’re either a beginner or haven’t spent enough time studying the language/standard library or important PEPs.
I don't think you can really blame Python for it. It's not like the language can (or should) prevent you from writing
if something == False
, it's perfectly valid code and it does work exactly the same as writing it idiomatically, so there's not really anything truly wrong with it.That's just the nature of language idioms, you have to learn the "culture" of that language to see how other people using it will expect you to do certain things. I think a good way to learn is to work on a project with more-experienced devs that can review your code and point out when you do things non-idiomatically, and you can also look through the code they're writing to see how they do things.
Yeah, but it’s a little awkward when Pythonistas laud the Python language design principles such as those in "The Zen of Python" like:
The unary
not
operator is probably very confusing, for instance:It is a bit confusing laid out like that, but there is at least a fairly simple underlying principle at work - True and False are guaranteed to behave like 1 and 0 (at least in Python 3).
Truthiness coercion wasn’t even the point I was trying to make, but it can also be confusing. Maybe I can try to make my point about Python’s
not
more concisely:Idioms are inherently part of a language, just like natural language. Just because you know English doesn’t mean you know all English idioms (esp. uncommon, archaic ones). E.g., Python’s dunder methods: I see a lot of beginner Python code from devs coming from other languages where classes have custom
show
,length
, etc. methods when they should be using__repr__
,__len__
etc.I find OOP in Python terse, increasing cognitive load. But it's beautiful and pleasant. OOP in Java, on the other hand, is ridiculously verbose, but also unambiguous by design. I'm just a beginner, but I suppose there's some middle ground to achieve here.
A question for the more experienced: how could I make Python OOP more self-evident (but not necessarily much more verbose)?
What are you trying to achieve? By declaring types you will inherently be verbose. You could, for example only give functions input & output parameters a type, which I already a big step in understanding the code
I have trouble with short-term memory (ADHD), and one of my main issues with OOP in Python is simply forgetting what things are and do, even on small programs. Looking-up essential stuff every 5 to 10 seconds break my "flow", requiring constant "cognitive reboots". I figured a bit more verbosity might help, but, since I'm a beginner, I tend to mimic whatever book, documentation or tutorial I'm following just because I don't know any better.
Your suggestions seem really good, could you maybe point to some layman-friendly articles or documentation that goes over these features?
I think for the very basic thing, this should suffice:
https://docs.python.org/3/library/typing.html
just let me know if you have trouble understanding anything in there.
I think this example covers the basic knowledge needed:
so you can type parameters (here the parameter is name) by using a colon, and you let the user
/interpreterknow that the return value is a string as well. Denoted by the arrow.here's a list of types: https://realpython.com/python-data-types/
I guess the most important are str, float and int. Of course this will get much more complex with time haha
Awesome, thanks! Besides clarity, what are the benefits of this feature?
You can run mypy (or some other checkers) against code with type annotations and it will tell you if you have any type errors. I think some IDEs can also use them to do a better job of suggesting variables/methods based on what makes sense with the types.
For example if I copy @ali's function and accidentally call it with a number instead of a string:
When I run mypy on that file it outputs:
That's a really contrived example that wouldn't really matter because your program would crash as soon as you tried to run it anyway, but it can help a lot in more complicated cases. For example maybe you have a function called
get_name()
that almost always returns a string, but can occasionally returnNone
if something goes wrong. If you do something like this:That looks totally reasonable and your program will work as long as
get_name()
does return a string, but it has the potential to crash in those rare cases where it returnsNone
. mypy will catch that and tell you about the potential error, because it knowsget_name()
doesn't always return a string butgreeting()
always needs one, so there's a mismatch.here's an interesting read on that: https://pawelmhm.github.io/python/static/typing/type/annotations/2016/01/23/typing-python3.html
In Python your program does not crash when running into invalid types, as it would in other languages, so without additional tools, the readability is the only advantage (as far as I know). The article mentions a library (mypy) which would precheck the types and tell you whether there is a type error. In languages like Java this is part of the design choice. In Python it is not
Personally I dislike OOP and avoid it when I can, but I’m glad that Python is flexible enough to support it. I don’t like some of the conventions and the syntax, but it’s OK. If possible, I try to use collection types from the
collections
module in the standard library such asnamedtuple
. Generally when I encounter very stateful Python APIs, they are hard to work with (such as Selenium’s Python driver). I find functional and imperative Python more my style.Which strand of functional programming you use the most?
I’m learning OOP with Java at uni. It feels like killing mosquitoes with a bazooka. I suppose it makes sense for large complex applications, but I can’t tell right now. But I don’t like it. It’s bureaucratic coding.
It’s not possible to write totally side-effect free code in Python, but generally, I try to not use any mutable data types, and if I do, I try to write functions to encapsulate any mutation. I like to pass around functions as first-class objects when it makes sense, such as making use of the
key
argument forsort
,min
, andmax
:Here’s an example of a program I wrote to compute Krippendorff’s alpha coefficient, a measure of inter-annotator reliability. I only made one class in that program, and that class is just a convenient namespace for consuming code to inject new delta functions. I actually don’t like my implementation there, and I suppose I could break it out into a separate module, but point was really just that I didn’t want to pollute the global namespace with lots of function names. I could also use a decorator (I did the decorator thing in this program with the
Format
class). I’m not totally happy with either solution, but they work.E.g.,
operator.methodcaller
is really neat to allow stuff likeDifference._delta
which is very convenient for allowing a command line driver to specify which delta method to use by interpreting a string argument as a class method name. If you are interested in writing functional Python, I highly recommend checking out theoperator
,functools
, anditertools
modules from the standard library.