Hello, I'm Chen Cheng.
Today I will share 15 Python bad habits. The main reason for these bad habits is that developers are inexperienced in Python. By abandoning these habits and writing code in a python way, you can not only improve the quality of your code, but also make a good impression on those who see the code~
1. Concatenate strings with + sign
Bad practices:
def manual_str_formatting(name, subscribers):
if subscribers > 100000: print("Wow " + name + "! you have " + str(subscribers) + " subscribers!") else: print("Lol " + name + " that's not many subs")
The adjusted method is to use f-string, and the efficiency will be higher:
def manual_str_formatting(name, subscribers):
# better if subscribers > 100000: print(f"Wow {name}! you have {subscribers} subscribers!") else: print(f"Lol {name} that's not many subs")
2. Use final instead of the context manager
Bad practices:
def finally_instead_of_context_manager(host, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((host, port)) s.sendall(b'Hello, world') finally: s.close()
The adjusted method is to use the context manager. Even if an exception occurs, the socket:: will be closed
def finally_instead_of_context_manager(host, port):
# close even if exception with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((host, port)) s.sendall(b'Hello, world')
3. Try closing the file manually
Bad practices:
def manually_calling_close_on_a_file(filename):
f = open(filename, "w") f.write("hello!\n") f.close()
The adjusted method is to use the context manager. Even if an exception occurs, the file will be closed automatically. If there is a context manager, you should first use:
def manually_calling_close_on_a_file(filename):
with open(filename) as f: f.write("hello!\n") # close automatic, even if exception
4. Nothing is written after except
Bad practices:
def bare_except():
while True: try: s = input("Input a number: ") x = int(s) break except: # oops! can't CTRL-C to exit print("Not a number, try again")
This will catch all exceptions, so that the program will not terminate after pressing CTRL-C. the adjusted method is
def bare_except():
while True: try: s = input("Input a number: ") x = int(s) break except Exception: # Better than this is to use ValueError print("Not a number, try again")
5. Function arguments use mutable objects
If the function parameters use mutable objects, the next call may produce unexpected results, which is a bad practice
def mutable_default_arguments():
def append(n, l=[]): l.append(n) return l l1 = append(0) # [0] l2 = append(1) # [0, 1]
The adjusted approach is as follows:
def mutable_default_arguments():
def append(n, l=None): if l is None: l = [] l.append(n) return l l1 = append(0) # [0] l2 = append(1) # [1]
6. Never use derivation
Bad practice
squares = {}
for i in range(10):
squares[i] = i * i
Adjusted approach
odd_squares = {i: i * i for i in range(10)}
7. Addiction for derivation
Although the derivation is easy to use, it can not sacrifice readability and bad practice
c = [
sum(a[n * i + k] * b[n * k + j] for k in range(n)) for i in range(n) for j in range(n)
]
The adjusted approach is as follows:
c = []
for i in range(n):
for j in range(n): ij_entry = sum(a[n * i + k] * b[n * k + j] for k in range(n)) c.append(ij_entry)
8. Use = = to judge whether it is a single case
Bad practice
def equality_for_singletons(x):
if x == None: pass if x == True: pass if x == False: pass
The adjusted approach is as follows:
def equality_for_singletons(x):
# better if x is None: pass if x is True: pass if x is False: pass
9. Use a C-like style for loop
Bad practice
def range_len_pattern():
a = [1, 2, 3] for i in range(len(a)): v = a[i] ... b = [4, 5, 6] for i in range(len(b)): av = a[i] bv = b[i]
...
The adjusted approach is as follows:
def range_len_pattern():
a = [1, 2, 3] # instead for v in a: ... # or if you wanted the index for i, v in enumerate(a): ... # instead use zip for av, bv in zip(a, b): ...
10. Not practical dict.items
Bad practice
def not_using_dict_items():
d = {"a": 1, "b": 2, "c": 3} for key in d: val = d[key] ...
The adjusted approach is as follows:
def not_using_dict_items():
d = {"a": 1, "b": 2, "c": 3} for key, val in d.items(): ...
11. Use time Time() counts the elapsed time
Bad practice
def timing_with_time():
start = time.time() time.sleep(1) end = time.time() print(end - start)
The adjusted approach is to use time perf_ Counter (), more accurate:
def timing_with_time():
# more accurate
start = time.perf_counter() time.sleep(1) end = time.perf_counter() print(end - start)
12. Use print instead of logging for logging
Bad practice
def print_vs_logging():
print("debug info") print("just some info") print("bad error")
The adjusted approach is as follows:
def print_vs_logging():
# versus # in main level = logging.DEBUG fmt = '[%(levelname)s] %(asctime)s - %(message)s' logging.basicConfig(level=level, format=fmt) # wherever logging.debug("debug info") logging.info("just some info") logging.error("uh oh :(")
13. shell=True when calling external commands
Bad practice
subprocess.run(["ls -l"], capture_output=True, shell=True)
If shell=True, passing ls -l to / bin/sh(shell) instead of ls program on Unix will cause subprocess to generate an intermediate shell process. In other words, using an intermediate shell means that variables, glob mode and other special shell functions in the command string will be preprocessed before the command runs. For example, $HOME will be processed before the echo command is executed.
The adjusted method is to refuse execution from the shell, as follows:
subprocess.run(["ls", "-l"], capture_output=True)
14. Never try to use numpy
Bad practice
def not_using_numpy_pandas():
x = list(range(100)) y = list(range(100)) s = [a + b for a, b in zip(x, y)]
The adjusted approach is as follows:
import numpy as np
def not_using_numpy_pandas():
# Faster performance x = np.arange(100) y = np.arange(100) s = x + y
15. Like import*
The adjusted approach is as follows:
from itertools import *
count()
In this case, no one knows that there are many variables in this script. It is better to:
from mypackage.nearby_module import awesome_function
def main():
awesome_function()
if name == '__main__':
main()
The above are some tips I summarized. That's the end
If you have any other supplementary or different opinions, you are welcome to discuss in the comments or send me a private letter~