names = ("John", "Lisa", "Terminator", "Python")
Don't do this.
semicolon_separated = names[0]
for name in names[1:]:
semicolon_separated += ";" + name
print(semicolon_separated)
John;Lisa;Terminator;Python
join
instead!¶semicolon_separated = ";".join(names)
print(semicolon_separated)
John;Lisa;Terminator;Python
or
in assignments¶The return value of a or b
:
a
if a
is truthyb
otherwiseYou can take advantage of this e.g. while writing variable assignments.
a = 0
b = None
c = "John Doe"
Instead of doing something like this:
my_variable = "default value"
if a:
my_variable = a
elif b:
my_variable = b
elif c:
my_variable = c
print(my_variable)
John Doe
my_variable = a or b or c or "default value"
print(my_variable)
John Doe
try
- except
- else
¶Don't use the following technique for checking if there was exceptions during execution of some block of code.
exception_occured = False
try:
# here would be the logic of your master piece
bad_calculation = 1 / 0
except ValueError as e:
print(f"Oh boi, some value error: {e}")
exception_occured = True
except Exception as e:
print(f"Oh boi, something bad happened: {e}")
exception_occured = True
if not exception_occured:
print("All went well!")
Oh boi, something bad happened: division by zero
try:
# here would be the logic of your master piece
bad_calculation = 1 / 0
except ValueError as e:
print(f"Oh boi, some keyerror: {e}")
except Exception as e:
print(f"Oh boi, something bad happened: {e}")
else:
print("All went well!")
Oh boi, something bad happened: division by zero
try
- finally
¶For scenarios where you want to do something always, even when there are exceptions.
Don't do it like this
def magical_calculation():
try:
# here would be the logic of your master piece
result = 1 / 0
except ZeroDivisionError:
print("This could be something important that should be done every time")
return 0
except Exception:
print("This could be something important that should be done every time")
return None
print("This could be something important that should be done every time")
return result
print(f"return value: {magical_calculation()}")
This could be something important that should be done every time return value: 0
def magical_calculation():
try:
# here would be the logic of your master piece
result = 1 / 0
except ZeroDivisionError:
return 0
except Exception:
return None
finally:
print("This could be something important that should be done every time")
return result
print(f"return value: {magical_calculation()}")
This could be something important that should be done every time return value: 0
Note: You can also have try
-except
-else
-finally
structure. In cases where exception is not raised inside try
, else
will be executed before finally
. If there is an expection, else
block is not executed.
One use case example is file I/O.
Don't play with files like this.
try:
some_file = open("tmp.txt", "w")
print(f"the file is now open: {not some_file.closed}")
# here would be some logic
finally:
some_file.close()
print(f"now it's closed: {some_file.closed}")
the file is now open: True now it's closed: True
with open("tmp.txt", "w") as some_file:
print(f"the file is now open: {not some_file.closed}")
# here would be some logic
print(f"now it's closed: {some_file.closed}")
the file is now open: True now it's closed: True
from contextlib import contextmanager
@contextmanager
def my_context():
print("Entering to my context")
yield
print("Exiting my context")
def do_stuff():
with my_context():
print("Doing stuff")
print("Doing some stuff outside my context")
do_stuff()
Entering to my context Doing stuff Exiting my context Doing some stuff outside my context
min()
& max()
¶secret_data = (1, 2, 5, 99, 8, -9)
No need to bake it yourself.
max_value = 0
for val in secret_data:
if val > max_value:
max_value = val
print(max_value)
99
max_value = max(secret_data)
print(max_value)
99
contextlib.suppress
- ignoring exceptions¶If there's a potential exception that is ok, don't handle it like this.
value = 0
try:
value = 1 / 0 # just for demonstrating purposes
except ZeroDivisionError:
pass
print(value)
0
from contextlib import suppress
value = 0
with suppress(ZeroDivisionError):
value = 1 / 0 # just for demonstrating purposes
print(value)
0
Instead of doing something like this.
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def get_full_name(self):
return f"{self.first_name} {self.last_name}"
def set_full_name(self, full_name):
parts = full_name.split()
if len(parts) != 2:
raise ValueError("Sorry, too difficult name")
self.first_name, self.last_name = parts
p = Person("John", "Doe")
print(p.get_full_name())
p.set_full_name("Lisa Doe")
print(p.get_full_name())
John Doe Lisa Doe
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
@full_name.setter
def full_name(self, name):
parts = name.split()
if len(parts) != 2:
raise ValueError("Sorry, too difficult name")
self.first_name, self.last_name = parts
p = Person("John", "Doe")
print(p.full_name)
p.full_name = "Lisa Doe"
print(p.full_name)
John Doe Lisa Doe