Clean code in Python refactor your legacy code base
Getting the most out of Python to improve your codebase Key Features Save maintenance costs by learning to fix your legacy codebase Learn the principles and techniques of refactoring Apply microservices to your legacy systems by implementing practical techniques Book Description Python is currently...
Otros Autores: | |
---|---|
Formato: | Libro electrónico |
Idioma: | Inglés |
Publicado: |
Birmingham ; Mumbai :
Packt Publishing
2018.
|
Edición: | 1st edition |
Materias: | |
Ver en Biblioteca Universitat Ramon Llull: | https://discovery.url.edu/permalink/34CSUC_URL/1im36ta/alma991009630692706719 |
Tabla de Contenidos:
- Cover
- Title Page
- Copyright and Credits
- Dedication
- Packt Upsell
- Contributors
- Table of Contents
- Preface
- Chapter 1: Introduction, Code Formatting, and Tools
- The meaning of clean code
- The importance of having clean code
- The role of code formatting in clean code
- Adhering to a coding style guide on your project
- Docstrings and annotations
- Docstrings
- Annotations
- Do annotations replace docstrings?
- Configuring the tools for enforcing basic quality gates
- Type hinting with Mypy
- Checking the code with Pylint
- Setup for automatic checks
- Summary
- Chapter 2: Pythonic Code
- Indexes and slices
- Creating your own sequences
- Context managers
- Implementing context managers
- Properties, attributes, and different types of methods for objects
- Underscores in Python
- Properties
- Iterable objects
- Creating iterable objects
- Creating sequences
- Container objects
- Dynamic attributes for objects
- Callable objects
- Summary of magic methods
- Caveats in Python
- Mutable default arguments
- Extending built-in types
- Summary
- References
- Chapter 3: General Traits of Good Code
- Design by contract
- Preconditions
- Postconditions
- Pythonic contracts
- Design by contract - conclusions
- Defensive programming
- Error handling
- Value substitution
- Exception handling
- Handle exceptions at the right level of abstraction
- Do not expose tracebacks
- Avoid empty except blocks
- Include the original exception
- Using assertions in Python
- Separation of concerns
- Cohesion and coupling
- Acronyms to live by
- DRY/OAOO
- YAGNI
- KIS
- EAFP/LBYL
- Composition and inheritance
- When inheritance is a good decision
- Anti-patterns for inheritance
- Multiple inheritance in Python
- Method Resolution Order (MRO)
- Mixins
- Arguments in functions and methods.
- How function arguments work in Python
- How arguments are copied to functions
- Variable number of arguments
- The number of arguments in functions
- Function arguments and coupling
- Compact function signatures that take too many arguments
- Final remarks on good practices for software design
- Orthogonality in software
- Structuring the code
- Summary
- References
- Chapter 4: The SOLID Principles
- Single responsibility principle
- A class with too many responsibilities
- Distributing responsibilities
- The open/closed principle
- Example of maintainability perils for not following the open/closed principle
- Refactoring the events system for extensibility
- Extending the events system
- Final thoughts about the OCP
- Liskov's substitution principle
- Detecting LSP issues with tools
- Detecting incorrect datatypes in method signatures with Mypy
- Detecting incompatible signatures with Pylint
- More subtle cases of LSP violations
- Remarks on the LSP
- Interface segregation
- An interface that provides too much
- The smaller the interface, the better
- How small should an interface be?
- Dependency inversion
- A case of rigid dependencies
- Inverting the dependencies
- Summary
- References
- Chapter 5: Using Decorators to Improve Our Code
- What are decorators in Python?
- Decorate functions
- Decorate classes
- Other types of decorator
- Passing arguments to decorators
- Decorators with nested functions
- Decorator objects
- Good uses for decorators
- Transforming parameters
- Tracing code
- Effective decorators - avoiding common mistakes
- Preserving data about the original wrapped object
- Dealing with side-effects in decorators
- Incorrect handling of side-effects in a decorator
- Requiring decorators with side-effects
- Creating decorators that will always work.
- The DRY principle with decorators
- Decorators and separation of concerns
- Analyzing good decorators
- Summary
- References
- Chapter 6: Getting More Out of Our Objects with Descriptors
- A first look at descriptors
- The machinery behind descriptors
- Exploring each method of the descriptor protocol
- __get__(self, instance, owner)
- __set__(self, instance, value)
- __delete__(self, instance)
- __set_name__(self, owner, name)
- Types of descriptors
- Non-data descriptors
- Data descriptors
- Descriptors in action
- An application of descriptors
- A first attempt without using descriptors
- The idiomatic implementation
- Different forms of implementing descriptors
- The issue of global shared state
- Accessing the dictionary of the object
- Using weak references
- More considerations about descriptors
- Reusing code
- Avoiding class decorators
- Analysis of descriptors
- How Python uses descriptors internally
- Functions and methods
- Built-in decorators for methods
- Slots
- Implementing descriptors in decorators
- Summary
- References
- Chapter 7: Using Generators
- Technical requirements
- Creating generators
- A first look at generators
- Generator expressions
- Iterating idiomatically
- Idioms for iteration
- The next() function
- Using a generator
- Itertools
- Simplifying code through iterators
- Repeated iterations
- Nested loops
- The iterator pattern in Python
- The interface for iteration
- Sequence objects as iterables
- Coroutines
- The methods of the generator interface
- close()
- throw(ex_type[, ex_value[, ex_traceback]])
- send(value)
- More advanced coroutines
- Returning values in coroutines
- Delegating into smaller coroutines - the yield from syntax
- The simplest use of yield from
- Capturing the value returned by a sub-generator.
- Sending and receiving data to and from a sub-generator
- Asynchronous programming
- Summary
- References
- Chapter 8: Unit Testing and Refactoring
- Design principles and unit testing
- A note about other forms of automated testing
- Unit testing and agile software development
- Unit testing and software design
- Defining the boundaries of what to test
- Frameworks and tools for testing
- Frameworks and libraries for unit testing
- unittest
- Parametrized tests
- pytest
- Basic test cases with pytest
- Parametrized tests
- Fixtures
- Code coverage
- Setting up rest coverage
- Caveats of test coverage
- Mock objects
- A fair warning about patching and mocks
- Using mock objects
- Types of mocks
- A use case for test doubles
- Refactoring
- Evolving our code
- Production code isn't the only thing that evolves
- More about unit testing
- Property-based testing
- Mutation testing
- A brief introduction to test-driven development
- Summary
- References
- Chapter 9: Common Design Patterns
- Considerations for design patterns in Python
- Design patterns in action
- Creational patterns
- Factories
- Singleton and shared state (monostate)
- Shared state
- The borg pattern
- Builder
- Structural patterns
- Adapter
- Composite
- Decorator
- Facade
- Behavioral patterns
- Chain of responsibility
- The template method
- Command
- State
- The null object pattern
- Final thoughts about design patterns
- The influence of patterns over the design
- Names in our models
- Summary
- References
- Chapter 10 : Clean Architecture
- From clean code to clean architecture
- Separation of concerns
- Abstractions
- Software components
- Packages
- Containers
- Use case
- The code
- Domain models
- Calling from the application
- Adapters
- The services
- Analysis
- The dependency flow
- Limitations.
- Testability
- Intention revealing
- Summary
- References
- Summing it all up
- Other Books You May Enjoy
- Index.