- Clean Code in Python : Develop maintainable and efficient code
- Saved searches
- Use saved searches to filter your results more quickly
- License
- PacktPublishing/Clean-Code-in-Python
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Clean code in Python Mariano Anaya — EuroPython 2016 · Clean code in Python EuroPython July 2016 — Bilbao, Spain Mariano Anaya
Clean Code in Python : Develop maintainable and efficient code
Key FeaturesEnhance your coding skills using the new features introduced in Python 3.9Implement the refactoring techniques and SOLID principles in PythonApply microservices to your legacy systems by implementing practical techniquesBook Description
Experienced professionals in every field face several instances of disorganization, poor readability, and testability due to unstructured code.
With updated code and revised content aligned to the new features of Python 3.9, this second edition of Clean Code in Python will provide you with all the tools you need to overcome these obstacles and manage your projects successfully.
The book begins by describing the basic elements of writing clean code and how it plays a key role in Python programming. You will learn about writing efficient and readable code using the Python standard library and best practices for software design.
The book discusses object-oriented programming in Python and shows you how to use objects with descriptors and generators. It will also show you the design principles of software testing and how to resolve problems by implementing software design patterns in your code. In the concluding chapter, we break down a monolithic application into a microservices-based one starting from the code as the basis for a solid platform.
By the end of this clean code book, you will be proficient in applying industry-approved coding practices to design clean, sustainable, and readable real-world Python code.
What you will learnSet up a productive development environment by leveraging automatic toolsLeverage the magic methods in Python to write better code, abstracting complexity away and encapsulating detailsCreate advanced object-oriented designs using unique features of Python, such as descriptorsEliminate duplicated code by creating powerful abstractions using software engineering principles of object-oriented designCreate Python-specific solutions using decorators and descriptorsRefactor code effectively with the help of unit testsBuild the foundations for solid architecture with a clean code base as its cornerstoneWho this book is for
This book is designed to benefit new as well as experienced programmers. It will appeal to team leads, software architects and senior software engineers who would like to write Pythonic code to save on costs and improve efficiency. The book assumes that you have a strong understanding of programming
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Clean Code in Python, published by Packt
License
PacktPublishing/Clean-Code-in-Python
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
This is the code repository for Clean Code in Python, published by Packt.
Refactor your legacy code base
Python is currently used in many different areas such as software construction, systems administration, and data processing. In all of these areas, experienced professionals can find examples of inefficiency, problems, and other perils, as a result of bad code. After reading this book, readers will understand these problems, and more importantly, how to correct them.
This book covers the following exciting features: Set up tools to effectively work in a development environment Explore how the magic methods of Python can help us write better code Examine the traits of Python to create advanced object-oriented design Understand removal of duplicated code using decorators and descriptors Effectively refactor code with the help of unit tests Learn to implement the SOLID principles in Python
If you feel this book is for you, get your copy today!
Instructions and Navigations
Create a virtual environment, and once activated run:
This will install the common dependencies. Besides this, each chapter might have additional ones, for which another make setup will have to be run inside that particular directory.
Each chapter has its corresponding directory given by its number.
Inside each chapter directory, tests can be run by:
This requires the make application installed (in Unix environments). In environments without access to the make command, the same code can be tested by running the commands on the Makefile :
python -m doctest *.py python -m unittest *.py
All of the code is organized into folders. For example, Chapter02.
The code will look like the following:
class Point: def __init__(self, lat, long): self.lat = lat self.long = long
Following is what you need for this book: This book will appeal to team leads, software architects and senior software engineers who would like to work on their legacy systems to save cost and improve efficiency. A strong understanding of Programming is assumed.
With the following software and hardware list you can run all code files present in the book (Chapter 1-10).
Software and Hardware List
Chapter | Software required | Hardware required |
---|---|---|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 | Python 3.7 | System with 4GB RAM |
10 | Docker | System with 4GB RAM |
Mariano Anaya is a software engineer who spends most of his time creating software with Python and mentoring fellow programmers. Mariano’s main areas of interests besides Python are software architecture, functional programming, distributed systems, and speaking at conferences.
He was a speaker at Euro Python 2016 and 2017. To know more about him, you can refer to his GitHub account with the username rmariano.
His speakerdeck username is rmariano.
Click here if you have any feedback or suggestions.
If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
About
Clean Code in Python, published by Packt
Clean code in Python Mariano Anaya — EuroPython 2016 · Clean code in Python EuroPython July 2016 — Bilbao, Spain Mariano Anaya
“You know you are working on clean code when each routine you read turns out to be pretty much what you expected.
You can call it beautiful code when the code also makes it look like the language was made for the problem.”
In Python: magic methods → “Pythonic” code
● What is “clean code”?○ Does one thing well○ Every f(x) does what you’d expect
● Why is it important?○ Code quality => Software quality○ Readability○ Agile development○ Code: blueprint
● Complex, obfuscated code● Duplicated code● Code that is not intention revealing
def elapse(year): days = 365 if year % 4 == 0 or (year % 100 == 0 and year % 400 == 0): days += 1 for day in range(1, days + 1): print(«Day <> of <>«.format(day, year))
Meaning and logic separation
def elapse(year): days = 365 if year % 4 == 0 or (year % 100 == 0 and year % 400 == 0): days += 1 for day in range(1, days + 1): print(«Day <> of <>«.format(day, year))
def elapse(year): days = 365 if is_leap(year): days += 1 .
● Often caused by the lack of meaningful abstractions● Unclear patterns usually drive to code duplication
● Hard to maintain, change, adapt● Error prone
● Avoid code duplication at all cost● Proposed solution: decorators
Duplicated code: decorators
def decorator(original_function): def inner(*args, **kwargs): # modify original function, or add extra logic return original_function(*args, **kwargs) return inner
General idea: take a function and modify it, returning a new one with the changed logic.
def update_db_indexes(cursor): commands = ( «»»REINDEX DATABASE transactional»»», ) try: for command in commands: cursor.execute(command) except Exception as e: logger.exception(«Error in update_db_indexes: %s», e) return -1 else: logger.info(«update_db_indexes run successfully») return 0
def db_status_handler(db_script_function): def inner(cursor): commands = db_script_function(cursor) function_name = db_script_function.__qualname__ try: for command in commands: cursor.execute(command) except Exception as e: logger.exception(«Error in %s: %s», function_name, e) return -1 else: logger.info(«%s run successfully», function_name) return 0 return inner
@db_status_handlerdef update_db_indexes(cursor): return ( «»»REINDEX DATABASE transactional»»», )
@db_status_handlerdef move_data_archives(cursor): return ( «»»INSERT INTO archive_orders SELECT * from orders WHERE order_date < '2016-01-01' """, """DELETE from orders WHERE order_date < '2016-01-01' """, )
● Abstract implementation details● Separate them from business logic● We could use:
○ Properties○ Context managers○ Magic methods
class PlayerStatus: . def accumulate_points(self, new_points): current_score = int(self.redis_connection.get(self.key) or 0) score = current_score + new_points self.redis_connection.set(self.key, score)
class PlayerStatus: . def accumulate_points(self, new_points): current_score = int(self.redis_connection.get(self.key) or 0) score = current_score + new_points self.redis_connection.set(self.key, score)
— implementation details— business logic
The kind of access I’d like to have
@property def points(self): return int(self.redis_connection.get(self.key) or 0)
@points.setter def points(self, new_points): self.redis_connection.set(self.key, new_points)
● Compute values for objects, based on other attributes● Avoid writing methods like get_*(), set_*()● Use Python’s syntax instead
class Stock: def __init__(self, categories=None): self.categories = categories or [] self._products_by_category = <>
def request_product_for_customer(customer, product, current_stock): product_available_in_stock = False for category in current_stock.categories: for prod in category.products: if prod.count > 0 and prod.id == product.id: product_available_in_stock = True if product_available_in_stock: requested_product = current_stock.request(product) customer.assign_product(requested_product) else: return «Product not available»
def request_product_for_customer(customer, product, current_stock): product_available_in_stock = False for category in current_stock.categories: for prod in category.products: if prod.count > 0 and prod.id == product.id: product_available_in_stock = True if product_available_in_stock: requested_product = current_stock.request(product) customer.assign_product(requested_product) else: return «Product not available»
Python was made for the problem
def request_product_for_customer(customer, product, current_stock): if product in current_stock: requested_product = current_stock.request(product) customer.assign_product(request_product) else: return «Product not available»
class Stock: . def __contains__(self, product): self.products_by_category() available = self.categories.get(product.category) .
● Some functions might require certain pre-conditions to be met before running
● … and we might also want to make sure to run other tasks upon completion.
Context Managersclass DBHandler: def __enter__(self): stop_database_service() return self
def __exit__(self, *exc): start_database_service().
with DBHandler(): run_offline_db_backup()
Context Managersclass db_status_handler(contextlib.ContextDecorator): def __enter__(self): stop_database_service() return self
def __exit__(self, *exc): start_database_service()
● Import contextlib● Python 3.2+
A more Pythonic code, should blend with Python’s words.
if product in current_stock:
● Python’s magic methods help us write more pythonic code.○ As well as context managers do.○ Use them to abstract the internal complexity and implementation
details.● Properties can enable better readability.● Decorators can help to:
○ Avoid duplication○ Separate logic
● PEP 8○ Define coding guidelines for the project○ Check automatically (as part of the CI)
● Docstrings (PEP 257)/ Function Annotations (PEP 3107)● Unit tests● Tools
○ Pycodestyle, Flake8, pylint, radon○ coala