I’ve been a Java/Kotlin developer for almost 5 years and transitioned to Python when I started working at Reasonal. There are benefits and drawbacks to all programming languages and I don't want to make a general comparison here. Python is a beautiful high-level programming language. You can learn the syntax fast and implement simple scripts right away. But that’s just the beginning: Down the road, you’ll find some obstacles that you didn’t expect.
What I want to share are some of the special quirks that Python has, some hurdles you will face when moving from Java to Python, as well as some tricks that I used to overcome them.
The obvious issue: Naming in Python
The first hurdle that most non-Python developers stumble upon when using Python is the naming. Arrays are called array
in almost every language - not so in Python, where they are called list
! To use a library you're usually using the include
keyword, but in python it’s import
. The array list of naming confusions is long, but those are just minor obstacles and you can get used to them quickly.
Let's continue onto the bigger issues.
No data types for variables in Python
Defining data types for variables is optional. You can simply use a variable and assign a string (so, somehow the variable type is implicitly set to string) but in the middle of coding you can assign a number to it and change it to a number type. Between programmers, that is bad practice, but the language allows you to do it.
That means your expectation and behavior of this variable have completely changed now: It was supposed to be a string but suddenly changed to a number. What if you assign another variable to it, which you don’t know the type of? What if it’s coming as the input of a function?
Generally, it’s better to define the data type for each variable, it will make the code much more readable and maintainable. My tip is: One of the libraries that is helpful here is typing
and one of the classes that I like is Optional
which is good for handling None
objects.
Retrieving the parameters of the REST API's
We are using flask
to implement our web application. One of the challenges I had was understanding the flask
query strings and the request body variables in a glance, so you know what input the API expects. In the middle of the code you can simply say request.get.args(“another_variable”)
and ask for a new query string. This is also true for the request body of POST requests.
The solutions that I found is using the marshmallow
or flask.expects_json
libraries - I prefer marshmallow
. By using marshmallow
in Python, you can define complex bodies, e.g:
class RequestBodySchema(Schema):
class MessageSchema(Schema):
type = fields.Str(required=True, validate=Length(max=MAX_SIZE))
class Content(Schema):
type = fields.Str(required=True, validate=Length(max=MAX_SIZE))
class NestedContent(Schema):
title = fields.Str(required=True, validate=Length(max=MAX_SIZE))
subtitle = fields.Str(required=False, validate=Length(max=MAX_SIZE))
class Meta:
# Include unknown fields in the deserialized output
unknown = INCLUDE
user_text = fields.List(
fields.Nested(NestedContent, required=True), required=False
)
class Meta:
# Include unknown fields in the deserialized output
unknown = INCLUDE
content = fields.List(fields.Nested(Content))
class Meta:
# Include unknown fields in the deserialized output
unknown = INCLUDE
user_name = fields.Str(required=True, validate=Length(max=MAX_SIZE))
action_type = fields.Str(required=True, validate=Length(max=MAX_SIZE, min=1))
corporation_id = fields.Int(required=True)
message = fields.Nested(MessageSchema(), required=True)
As you see it's quite complicated and a bit error prune, but it's better than not having anything.
Python modules follow a Singleton pattern
This one is not necessarily a pain, but it is important to be aware of this difference to Java and other programming languages:
Modules are Singleton
in Python, so if two different Python modules call another module, the scripts of the latter one will run just once. Be aware of setting some variables there. In order to get more familiar with Singleton
design patter, I suggest you this link: https://refactoring.guru/design-patterns/singleton, you can also see some examples therein.
Back to data types again!
When variables are simple data types like string
, int
, etc., life is still pretty manageable. However, when variables in a Python code are supposed to be instances of classes, you sometimes want to find out which class they are - suddenly, life is not easy anymore. You can not simply see the internal functions/attributes of that object and this becomes a real problem. Especially, when they become the input to a function and you have no idea to what class this variable belongs to.
Pylance
is one of the VS code extensions that can be helpful if you want to set or find the data type of variables.
But, I want to stress that it’s better to explicitly determine the data type of variables in Python :)
Let me give you an example: When inside a function and there are inputs like request
or db_session
, where, e.g, db_session
is supposed to be an instance of Session
in sqlalchemy.orm
. You can simply call the internal functions of that object, and during runtime it will work perfectly, but if you call a wrong function, you'll only get an error during runtime!
So try to use data types as much as possible to make the life of others and future "you" easier :)
Is it pass by value or pass by reference?
None and both! It’s a mystery. In Python, you can say it's both pass by value or pass by reference. Life would be simpler if Python had picked one of them, just like other programming languages. Python is pass by object reference. I suggest this article to get more familiar with the concept and also see how mutable
and immutable
objects are related to it.
DB migrations
This one is not a big deal at all, but worth mentioning. We use Alembic
for our MySql DB migrations, and we were not able to use Enum
for our DB columns because the changes of Enum
were not detected by Alembic
. Enum
is supported by Alembic
but it picks the values just once - be aware.
What to take away when using Python as a Java developer
I hope I could shed some light onto some of the difficulties or things to watch out for when using Python as a non-Python developer. Do let me know if you have questions, or if you found other obstacles and/or tips to overcome them.
Of course, we are also always looking for talent, too, find job openings here or contact us via our homepage.