Home Page Icon
Home Page
Table of Contents for
Technical requirements
Close
Technical requirements
by Steven F. Lott
Mastering Object-Oriented Python - Second Edition
Title Page
Copyright and Credits
Mastering Object-Oriented Python Second Edition
About Packt
Why subscribe?
Contributors
About the author
About the reviewers
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Code in Action
Conventions used
Get in touch
Reviews
Section 1: Tighter Integration Via Special Methods
Preliminaries, Tools, and Techniques
Technical requirements
About the Blackjack game
Playing the game
Blackjack player strategies
Object design for simulating Blackjack
The Python runtime and special methods
Interaction, scripting, and tools
Selecting an IDE
Consistency and style
Type hints and the mypy program
Performance – the timeit module
Testing – unittest and doctest
Documentation – sphinx and RST markup
Installing components
Summary
The __init__() Method
Technical requirements
The implicit superclass – object
The base class object __init__() method
Implementing __init__() in a superclass
Creating enumerated constants
Leveraging __init__() via a factory function
Faulty factory design and the vague else clause
Simplicity and consistency using elif sequences
Simplicity using mapping and class objects
Two parallel mappings
Mapping to a tuple of values
The partial function solution
Fluent APIs for factories
Implementing __init__() in each subclass
Composite objects
Wrapping a collection class
Extending a collection class
More requirements and another design
Complex composite objects
Complete composite object initialization
Stateless objects without __init__()
Some additional class definitions
Multi-strategy __init__()
More complex initialization alternatives
Initializing with static or class-level methods
Yet more __init__() techniques
Initialization with type validation
Initialization, encapsulation, and privacy
Summary
Integrating Seamlessly - Basic Special Methods
Technical requirements
The __repr__() and __str__() methods
Simple __str__() and __repr__()
Collection __str__() and __repr__()
The __format__() method
Nested formatting specifications
Collections and delegating format specifications
The __hash__() method
Deciding what to hash
Inheriting definitions for immutable objects
Overriding definitions for immutable objects
Overriding definitions for mutable objects
Making a frozen hand from a mutable hand
The __bool__() method
The __bytes__() method
The comparison operator methods
Designing comparisons
Implementation of a comparison of objects of the same class
Implementation of a comparison of the objects of mixed classes
Hard totals, soft totals, and polymorphism
A mixed class comparison example
The __del__() method
The reference count and destruction
Circular references and garbage collection
Circular references and the weakref module
The __del__() and close() methods
The __new__() method and immutable objects
The __new__() method and metaclasses
Metaclass example – class-level logger
Summary
Attribute Access, Properties, and Descriptors
Technical requirements
Basic attribute processing
Attributes and the __init__() method
Creating properties
Eagerly computed properties
The setter and deleter properties
Using special methods for attribute access
Limiting attribute names with __slots__
Dynamic attributes with __getattr__()
Creating immutable objects as a NamedTuple subclass
Eagerly computed attributes, dataclasses, and __post_init__()
Incremental computation with __setattr__()
The __getattribute__() method
Creating descriptors
Using a non-data descriptor
Using a data descriptor
Using type hints for attributes and properties
Using the dataclasses module
Attribute Design Patterns
Properties versus attributes
Designing with descriptors
Summary
The ABCs of Consistent Design
Technical requirements
Abstract base classes
Base classes and polymorphism
Callable
Containers and collections
Numbers
Some additional abstractions
The iterator abstraction
Contexts and context managers
The abc and typing modules
Using the __subclasshook__() method
Abstract classes using type hints
Summary, design considerations, and trade-offs
Looking forward
Using Callables and Contexts
Technical requirements
Designing callables
Improving performance
Using memoization or caching
Using functools for memoization
Aiming for simplicity using a callable interface
Complexities and the callable interface
Managing contexts and the with statement
Using the decimal context
Other contexts
Defining the __enter__() and __exit__() methods
Handling exceptions
Context manager as a factory
Cleaning up in a context manager
Summary
Callable design considerations and trade-offs
Context manager design considerations and trade-offs
Looking forward
Creating Containers and Collections
Technical requirements
ABCs of collections
Examples of special methods
Using the standard library extensions
The typing.NamedTuple class
The deque class
The ChainMap use case
The OrderedDict collection
The defaultdict subclass
The counter collection
Creating new kinds of collections
Narrowing a collection's type
Defining a new kind of sequence
A statistical list
Choosing eager versus lazy calculation
Working with __getitem__(), __setitem__(), __delitem__(), and slices
Implementing __getitem__(), __setitem__(), and __delitem__()
Wrapping a list and delegating
Creating iterators with __iter__()
Creating a new kind of mapping
Creating a new kind of set
Some design rationale
Defining the Tree class
Defining the TreeNode class
Demonstrating the binary tree bag
Design considerations and tradeoffs
Summary
Creating Numbers
Technical requirements
ABCs of numbers
Deciding which types to use
Method resolution and the reflected operator concept
The arithmetic operator's special methods
Creating a numeric class
Defining FixedPoint initialization
Defining FixedPoint binary arithmetic operators
Defining FixedPoint unary arithmetic operators
Implementing FixedPoint reflected operators
Implementing FixedPoint comparison operators
Computing a numeric hash
Designing more useful rounding
Implementing other special methods
Optimization with the in-place operators
Summary
Decorators and Mixins - Cross-Cutting Aspects
Technical requirements
Class and meaning
Type hints and attributes for decorators
Attributes of a function
Constructing a decorated class
Some class design principles
Aspect-oriented programming
Using built-in decorators
Using standard library decorators
Using standard library mixin classes
Using the enum with mixin classes
Writing a simple function decorator
Creating separate loggers
Parameterizing a decorator
Creating a method function decorator
Creating a class decorator
Adding methods to a class
Using decorators for security
Summary
Section 2: Object Serialization and Persistence
Serializing and Saving - JSON, YAML, Pickle, CSV, and XML
Technical requirements
Understanding persistence, class, state, and representation
Common Python terminology
Filesystem and network considerations
Defining classes to support persistence
Rendering blogs and posts
Dumping and loading with JSON
JSON type hints
Supporting JSON in our classes
Customizing JSON encoding
Customizing JSON decoding
Security and the eval() issue
Refactoring the encode function
Standardizing the date string
Writing JSON to a file
Dumping and loading with YAML
Formatting YAML data on a file
Extending the YAML representation
Security and safe loading
Dumping and loading with pickle
Designing a class for reliable pickle processing
Security and the global issue
Dumping and loading with CSV
Dumping simple sequences into CSV
Loading simple sequences from CSV
Handling containers and complex classes
Dumping and loading multiple row types into a CSV file
Filtering CSV rows with an iterator
Dumping and loading joined rows into a CSV file
Dumping and loading with XML
Dumping objects using string templates
Dumping objects with xml.etree.ElementTree
Loading XML documents
Summary
Design considerations and tradeoffs
Schema evolution
Looking forward
Storing and Retrieving Objects via Shelve
Technical requirements
Analyzing persistent object use cases
The ACID properties
Creating a shelf
Designing shelvable objects
Designing objects with type hints
Designing keys for our objects
Generating surrogate keys for objects
Designing a class with a simple key
Designing classes for containers or collections
Referring to objects via foreign keys
Designing CRUD operations for complex objects
Searching, scanning, and querying
Designing an access layer for shelve
Writing a demonstration script
Creating indexes to improve efficiency
Creating a cache
Adding yet more index maintenance
The writeback alternative to index updates
Schema evolution
Summary
Design considerations and tradeoffs
Application software layers
Looking forward
Storing and Retrieving Objects via SQLite
Technical requirements
SQL databases, persistence, and objects
The SQL data model – rows and tables
CRUD processing via SQL DML statements
Querying rows with the SQL SELECT statement
SQL transactions and the ACID properties
Designing primary and foreign database keys
Processing application data with SQL
Implementing class-like processing in pure SQL
Mapping Python objects to SQLite BLOB columns
Mapping Python objects to database rows manually
Designing an access layer for SQLite
Implementing container relationships
Improving performance with indices
Adding an ORM layer
Designing ORM-friendly classes
Building the schema with the ORM layer
Manipulating objects with the ORM layer
Querying posts that are given a tag
Defining indices in the ORM layer
Schema evolution
Summary
Design considerations and tradeoffs
Mapping alternatives
Key and key design
Application software layers
Looking forward
Transmitting and Sharing Objects
Technical requirements
Class, state, and representation
Using HTTP and REST to transmit objects
Implementing CRUD operations via REST
Implementing non-CRUD operations
The REST protocol and ACID
Choosing a representation – JSON, XML, or YAML
Using Flask to build a RESTful web service
Problem-domain objects to transfer
Creating a simple application and server
More sophisticated routing and responses
Implementing a REST client
Demonstrating and unit testing the RESTful services
Handling stateful REST services
Designing RESTful object identifiers
Multiple layers of REST services
Using a Flask blueprint
Registering a blueprint 
Creating a secure REST service
Hashing user passwords
Implementing REST with a web application framework
Using a message queue to transmit objects
Defining processes
Building queues and supplying data
Summary
Design considerations and tradeoffs
Schema evolution
Application software layers
Looking forward
Configuration Files and Persistence
Technical requirements
Configuration file use cases
Representation, persistence, state, and usability
Application configuration design patterns
Configuring via object construction
Implementing a configuration hierarchy
Storing the configuration in INI files
Handling more literals via the eval() variants
Storing the configuration in PY files
Configuration via class definitions
Configuration via SimpleNamespace
Using Python with exec() for the configuration
Why exec() is a non-problem
Using ChainMap for defaults and overrides
Storing the configuration in JSON or YAML files
Using flattened JSON configurations
Loading a YAML configuration
Storing the configuration in properties files
Parsing a properties file
Using a properties file
Using XML files – PLIST and others
Customized XML configuration files
Summary
Design considerations and trade-offs
Creating a shared configuration
Schema evolution
Looking forward
Section 3: Object-Oriented Testing and Debugging
Design Principles and Patterns
Technical requirements
The SOLID design principles
The Interface Segregation Principle
The Liskov Substitution Principle
The Open/Closed Principle
The Dependency Inversion Principle
The Single Responsibility Principle
A SOLID principle design test
Building features through inheritance and composition
Advanced composition patterns
Parallels between Python and libstdc++
Summary
The Logging and Warning Modules
Technical requirements
Creating a basic log
Creating a class-level logger
Configuring loggers
Starting up and shutting down the logging system
Naming loggers
Extending logger levels
Defining handlers for multiple destinations
Managing propagation rules
Configuration Gotcha
Specialized logging for control, debugging, audit, and security
Creating a debugging log
Creating audit and security logs
Using the warnings module
Showing API changes with a warning
Showing configuration problems with a warning
Showing possible software problems with a warning
Advanced logging – the last few messages and network destinations
Building an automatic tail buffer
Sending logging messages to a remote process
Preventing queue overrun
Summary
Design considerations and trade-offs
Looking ahead
Designing for Testability
Technical requirements
Defining and isolating units for testing
Minimizing dependencies
Creating simple unit tests
Creating a test suite
Including edge and corner cases
Using mock objects to eliminate dependencies
Using mocks to observe behaviors
Using doctest to define test cases
Combining doctest and unittest
Creating a more complete test package
Using setup and teardown
Using setup and teardown with OS resources
Using setup and teardown with databases
The TestCase class hierarchy
Using externally defined expected results
Using pytest and fixtures
Assertion checking
Using fixtures for test setup
Using fixtures for setup and teardown
Building parameterized fixtures
Automated integration or performance testing
Summary
Design considerations and trade-offs
Looking forward
Coping with the Command Line
Technical requirements
The OS interface and the command line
Arguments and options
Using the pathlib module
Parsing the command line with argparse
A simple on–off option
An option with an argument
Positional arguments
All other arguments
--version display and exit
--help display and exit
Integrating command-line options and environment variables
Providing more configurable defaults
Overriding configuration file settings with environment variables
Making the configuration aware of the None values
Customizing the help output
Creating a top-level main() function
Ensuring DRY for the configuration
Managing nested configuration contexts
Programming in the large
Designing command classes
Adding the analysis command subclass
Adding and packaging more features into an application
Designing a higher-level, composite command
Additional composite Command design patterns
Integrating with other applications
Summary
Design considerations and trade-offs
Looking forward
Module and Package Design
Technical requirements
Designing a module
Some module design patterns
Modules compared with classes
The expected content of a module
Whole modules versus module items
Designing a package
Designing a module-package hybrid
Designing a package with alternate implementations
Using the ImportError exception
Designing a main script and the __main__ module
Creating an executable script file
Creating a __main__ module
Programming in the large
Designing long-running applications
Organizing code into src, scripts, tests, and docs
Installing Python modules
Summary
Design considerations and tradeoffs
Looking forward
Quality and Documentation
Technical requirements
Writing docstrings for the help() function
Using pydoc for documentation
Better output via RST markup
Blocks of text
The RST inline markup
RST directives
Learning RST
Writing effective docstrings
Writing file-level docstrings, including modules and packages
Writing API details in RST markup
Writing class and method function docstrings
Writing function docstrings
More sophisticated markup techniques
Using Sphinx to produce the documentation
Using Sphinx quickstart
Writing Sphinx documentation
Filling in the 4+1 views for documentation
Writing the implementation document
Creating Sphinx cross-references
Refactoring Sphinx files into directories
Handling legacy documents
Writing the documentation
Literate programming
Use cases for literate programming
Working with a literate programming tool
Summary
Design considerations and tradeoffs
Other Books You May Enjoy
Leave a review - let other readers know what you think
Search in book...
Toggle Font Controls
Playlists
Add To
Create new playlist
Name your new playlist
Playlist description (optional)
Cancel
Create playlist
Sign In
Email address
Password
Forgot Password?
Create account
Login
or
Continue with Facebook
Continue with Google
Sign Up
Full Name
Email address
Confirm Email Address
Password
Login
Create account
or
Continue with Facebook
Continue with Google
Prev
Previous Chapter
Storing and Retrieving Objects via Shelve
Next
Next Chapter
Analyzing persistent object use cases
Technical requirements
The code files for this chapter are available at
https://git.io/fj2Ur
.
Add Highlight
No Comment
..................Content has been hidden....................
You can't read the all page of ebook, please click
here
login for view all page.
Day Mode
Cloud Mode
Night Mode
Reset