Here are a few key skills and concepts you should learn when transitioning from JavaScript to Python:
- Syntax: Python syntax is quite different from JavaScript. For example, Python uses indentation for blocks instead of
{}
. Also, Python usesNone
instead ofnull
, and there is noundefined
in Python. Understanding the syntax will be key in learning Python effectively. - Typing: Python is dynamically typed like JavaScript, but Python 3.5 introduced optional type hints. You can declare the expected types of function parameters and return values. This feature is not often used in JavaScript.
- Data Structures: Python includes a number of robust built-in data types that you'll want to be familiar with, such as lists (similar to JavaScript arrays), dictionaries (similar to JavaScript objects), sets, and tuples.
- List Comprehensions: Python offers a powerful construct called "list comprehension" that allows you to create lists in a very concise way.
- Functions and Decorators: Python has first-class functions like JavaScript. You should understand how Python treats functions and how to use decorators to modify the behavior of functions and classes.
- Error Handling: Python's
try
/except
blocks are similar to JavaScript'stry
/catch
, but there are subtle differences. Python also uses theelse
andfinally
clauses in error handling. - Libraries and Frameworks: Familiarize yourself with the Python standard library, and also with external libraries and frameworks that are most relevant to your work, like Flask or Django for web development, NumPy and pandas for data analysis, etc.
- Object-Oriented Programming: While JavaScript has prototype-based inheritance, Python has a more traditional class-based inheritance system. You should understand classes in Python, how inheritance works, and how to use special "dunder" methods to control how your classes behave.
- Iterators and Generators: These are advanced concepts that can be very useful in Python. While JavaScript has similar concepts (for example, generators introduced in ES6), the Python approach could feel different.
- Concurrency and Parallelism: Python's approach to concurrency is different from JavaScript. Python has threads, a Global Interpreter Lock (GIL), and also features like async IO (Python coroutines) which may be similar to JavaScript's Promises and async/await.
# Create a virtual environment to isolate our package dependencies locally:
python -m venv env ## you can replace `env` with whatever
# Activate it
source env/bin/activate
# On Windows use `env\Scripts\activate`
# Deactivate when you’re done:
deactivate
Find packages: https://pypi.org/
pip3 install torch torchvision
Save requirements file:
pip3 freeze > requirements.txt
Install from requirements:
pip3 install -r requirements.txt
https://vercel.com/docs/concepts/functions/serverless-functions/runtimes/python#python-version
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask = "*"
[requires]
python_version = "3.9"
python3
Type quit()
or press Ctrl+D to quit (Windows: Ctrl+Z)
import math
from math import pi
Method 1: Import a specific function you want from my_lib.py
:
from my_lib import my_function
Method 2: Import the entire file:
import my_lib as my_lib
my_lib.my_function(a, b)
Local file in same folder:
from .my_lib import MyLib
- Text string:
str
, multiline with 3 quotes (single"
or double'
) - Number:
int
,float
,complex
- Boolean:
bool
- Collections:
list
(“array”) e.g.["apple", "banana", "cherry"]
, get value withmy_list[0]
, lengthlen(my_list)
(ordered, changeable)tuple
e.g.("apple", "banana", "cherry")
(ordered, unmutable)dict
(“object/collection”) e.g.{"name": "value"}
, getvalue
withmy_dict["name"]
(ordered from v3.7, changeable)- Merge dicts with
new_dict = old_dict | new_values
- Merge dicts with
set
e.g.{"string", 123, true}
(unordered, unindexed, can add/remove but not change items)frozenset
range
e.g.range(6)
orrange(0, 10, 2)
- Binary:
bytes
e.g.b"Hello"
bytearray
memoryview
- NoneType:
None
Check type with type(variable)
Cast with e.g. str(123)
sub_string = string[0:5]
my_list.get(0, "default value")
len(my_list)
Filter:
filtered_big_list = [item for item in big_list if item.get('name') == 'X']
filtered_big_list = list(filter(lambda item: item.get('name') == 'X', big_list))
my_dict.get("listKey", "default value")
def my_function():
print("Hello from a function")
return 1 # Or 'pass'
Lambda (short) function (like JavaScript arrow function): add10 = lambda n: n + 10
String function: f'This is dynamic: {expression}'
Named parameters when calling: my_function(param1 = 100)
pi: float = 3.142
def greet(name: str = "Joan") -> str:
return "Hello, " + name
For multiple return values, use Tuple
:
from typing import List, Tuple
class Calculator:
def other_costs_specification(costs_for_owner) -> Tuple[List[List], List[List]]:
Try/catch:
try:
await my_function()
except Exception as error:
return json({ error: error })
Throw error:
raise TypeError('Argument should be an integer or a float value')
Error types:
TypeError
, ValueError
, KeyError
, IndexError
, RuntimeError
, NotImplementedError
Custom error type:
class MyCustomError(Exception):
pass
raise MyCustomError("This is a custom error")
def divide(numerator: float, denominator: float) -> float:
if not isinstance(numerator, (int, float)):
raise TypeError('Numerator must be a number')
if not isinstance(denominator, (int, float)):
raise TypeError('Denominator must be a number')
if denominator == 0:
raise ValueError('Cannot divide by zero')
return numerator / denominator
Multiple types:
def greet(name: Optional[str] = None):
def greet(name: Union[str, None] = None):
# person = Person(name, age).create()
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# person.an_object_method(param)
def an_object_method(self, param):
# code...
# Person.a_static_method(param)
@staticmethod
def a_static_method(param):
# code...
Subclassing:
class Person(species.Human):
print("Hello World!")
vat=f"{round(0.20 * total_amount, 2):2f}"
if b > a:
print("b is greater than a")
elif a == b:
print("a and b are equal")
else:
print("a is greater than b")
Boolean:
and/or/not
Ternary expression:
device = "cuda" if torch.cuda.is_available() else "cpu"
Includes:
if person in employees:
print("You’re an employee")
for i in range(1, 5):
print(i)
break
, continue
(skip to next)
while i < 6:
print(i)
i += 1
new_list = map(lambda n: n + 10, my_list)
async def ping_local():
return await ping_server('192.168.1.1')
https://realpython.com/primer-on-python-decorators/
def print_function_name(func):
def wrapper(*args, **kwargs):
print(f"\n◆ Calling '{func.__name__}'...\n", args[1:])
return func(*args, **kwargs)
return wrapper
@print_function_name
def say_whee():
print("Whee!")
# If no command line arguments
if len(sys.argv) == 1:
print('No command line arguments')
sys.exit()
else:
get_files_in_folder(sys.argv[1])
import os
my_variable = os.environ['MY_VARIABLE']
def get_files_in_folder(folder):
files = os.listdir(folder)
for file in files:
file_path = os.path.join(folder, file)
print(file_path)
- Docstrings and
help()
- num in range(3, 6)
- Make a package https://github.com/learnbyexample/100_page_python_intro/blob/main/100_page_python_intro.md#creating-your-own-package
- PDB debugger
Unit testing libraries in Python such as PyUnit and PyTest
Linting: Flake8
pip install flake8
Formatting: Black:
pip3 install black
https://betterprogramming.pub/simple-hacks-to-automate-python-code-beautification-5ad934cf5a29
- Django REST Framework: big and complete
- Flask: smaller
Create a app.py
:
#!/usr/bin/env python
# encoding: utf-8
import json
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return json.dumps({ 'message': 'Hello World!' })
Install Flask:
pip3 install Flask
then run:
export FLASK_APP=main.py
flask run
Hot reload:
export FLASK_DEBUG=true
and open http://127.0.0.1:5000/
export FLASK_APP=main.py
export FLASK_DEBUG=true
export FLASK_RUN_HOST=localhost
export FLASK_RUN_PORT=4001