Python Best Practice Patterns by Vladimir Keleshev (Notes)
Python Best Practice Patterns by Vladimir Keleshev (Notes)
com
These are my notes from Vladimir Keleshev's talk en tled "Python Best
Prac ce Pa erns", given on May , at the Python Meetup in
Denmark. The original video is here (about minutes long).
Note: Some of the code examples have been has been modi ed from the original
presenta on based on readers' feedback.
Composed method
• Divide program into methods that perform one task
• Keep all opera on in a method at the same level of abstrac on
• Di erent levels of abstrac on: bitmaps, lesystem opera ons, playing sounds...
1 # Better
2 class Boiler:
3 def safety_check(self):
4 if any([self.temperature > MAX_TEMPERATURE,
5 self.pressure > MAX_PRESSURE]):
6 if not self.shutdown():
7 self.alarm()
8
9 def alarm(self):
10 with open(BUZZER_MP3_FILE) as f:
11 play_sound(f.read())
12
13 @property
14 def pressure(self):
15 pressure_psi = abb_f100.register / F100_FACTOR
16 return psi_to_pascal(pressure_psi)
17 ...
https://stevenloria.com/python-best-practice/ 1/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
Constructor method
• provide constructors that create well-formed instances
• Pass all required parameters to them
1 # At initiation `point` is not well-formed
2 point = Point()
3 point.x = 12
4 point.y = 5
5
6 # Better
7 point = Point(x=12, y=5)
Method objects
• How do you code a method where many lines of code share many arguments and
temporary variables?
1 def send_task(self, task, job, obligation):
2 ...
3 processed = ...
4 ...
https://stevenloria.com/python-best-practice/ 2/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
5 copied = ...
6 ...
7 executed = ...
8 100 more lines
• Can't be solved by making many small methods (would use more code)
1 class TaskSender:
2 def __init__(self, task, job obligation):
3 self.task = task
4 self.job = job
5 self.obligation = obligation
6 self.processed = []
7 self.copied = []
8 self.executed = []
9
10 def __call__(self):
11 self.prepare()
12 self.process()
13 self.execute()
14 ...
Method comment
• small methods can be more e ec ve than comments
1 if self.flags & 0b1000: # Am I visible?
2 ...
3
4 # Better
5 ...
6 @property
7 def is_visible(self):
8 return self.flags & 0b1000
9
10 if self.is_visible:
11 ...
Choosing message
1 # Bad
2 if type(entry) is Film:
https://stevenloria.com/python-best-practice/ 4/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
3 responsible = entry.producer
4 else:
5 responsible = entry.author
6
7 # Shouldn't use type() or isinstance() in conditional --> smelly
8
9 # Better
10 class Film:
11 ...
12 @property
13 def responsible(self):
14 return self.producer
15
16 entry.responsible
10 )
11 return self
12
13 # If you want to subclass SomeProtocol, you would have to overwrite every m
14
15 # Better
16 class SomeProtocol:
17 _default_port = 1234
18 ...
19 def __enter__(self):
20 self._client = socket()
21 self._client.connect(
22 (self.host,
23 self.port or self._default_port))
https://stevenloria.com/python-best-practice/ 6/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
Temporary variable
1 # Meh
2 class Rectangle:
3 def bottom_right(self):
4 return Point(self.left + self.width,
5 self.top + self.height)
6
7 # Better to use temporary variables for readability
8 class Rectangle:
9 ...
10 def bottom_right(self):
11 right = self.left + self.width
12 bottom = self.top + self.height
13 return Point(right, bottom)
14
https://stevenloria.com/python-best-practice/ 7/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
Sets
• Can o en use sets instead of combina on of for loops
1 item in a_set
2 item not in a_set
3
4 # a_set <= other
5 a_set.is_subset(other)
6
7 # a_set | other
8 a_set.union(other)
9
10 # a_set & other
11 a_set.intersection(other)
12
13 # a_set - other
14 a_set.difference(other)
Equality method
1 obj == obj2
2 obj1 is obj2
3
4 class Book:
5 ...
6 def __eq__(self, other):
7 if not isinstance(other, self.__class__):
8 return NotImplemented
9 return (self.author == other.author and
10 self.title == other.title)
Hashing method
1 class Book:
2 ...
3 def __hash__(self):
4 return hash(self.author) ^ hash(self.other)
https://stevenloria.com/python-best-practice/ 8/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
Sorted collection
1 class Book:
2 ...
3 def __lt__(self, other):
4 return (self.author, self.title) < (other.author, other.title)
Concatenation
1 class Config:
2 def __init__(self, **entries):
3 self.entries = entries
4
5 def __add__(self, other):
6 entries = (self.entries.items() +
7 other.entries.items())
8 return Config(**entries)
9 default_config = Config(color=False, port=8080)
10 config = default_config + Config(color=True)
Cascades
https://stevenloria.com/python-best-practice/ 9/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
• Instead of wri ng methods without return values, make them return self
• allows cascading of methods
1 # Instead of this
2 self.release_water()
3 self.shutdown()
4 self.alarm()
5
6 class Reactor:
7 ...
8 def release_water(self):
9 self.valve.open()
10 return self
11
12 self.release_water().shutdown().alarm()
Further reading
• Smalltalk Best Prac ce Pa erns
• Not just for Smalltalk: applicable to Python, Ruby, and many other languages
https://stevenloria.com/python-best-practice/ 10/11
01/07/2019 Python Best Practice Patterns by Vladimir Keleshev (Notes) | stevenloria.com
Edits
March , : Fix condi onal in Composed Method sec on. Thanks Rufus Smith.
Please send comments by email. I welcome your feedback, advice, and cri cism.
https://stevenloria.com/python-best-practice/ 11/11