Effective Python 4 Flashcards

(322 cards)

1
Q

“Does Python have language features that help construct well-defined APIs?”

A

“Python has language features that help you construct well-defined APIs with clear interface boundaries.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

“Has the Python community established best practices?”

A

“The Python community has established best practices to maximize the maintainability of code over time.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

“Do standard tools enable large teams to work together?”

A

“Some standard tools that ship with Python enable large teams to work together across disparate environments.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

“Does collaborating require being deliberate about code?”

A

“Collaborating with others on Python programs requires being deliberate on how you write your code.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

“Will you likely use code written by someone else?”

A

“Even if you’re working on your own

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

“Why understand Python collaboration mechanisms?”

A

“It’s important to understand the mechanisms that make it easy to collaborate with other Python programmers.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

“Does Python have a central repository of modules?”

A

“Python has a central repository of modules (PyPI) that you can install and use in your programs.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

“Who builds and maintains PyPI modules?”

A

“These modules are built and maintained by people like you: the Python community.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

“When should you look to PyPI?”

A

“When you find yourself facing an unfamiliar situation

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

“What tool do you need for the Package Index?”

A

“To use the Package Index

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

“How should you run pip?”

A

“pip can be run with python3 -m pip to ensure that packages are installed for the correct version of Python on your system.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

“What tool is pip best used with?”

A

“pip is best used together with venv to consistently track sets of packages to install for your projects.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

“Can you create your own PyPI packages?”

A

“You can also create your own PyPI packages to share with the Python community.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

“Can you host private package repositories?”

A

“You can host your own private package repositories with pip.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

“Do PyPI modules have software licenses?”

A

“Each module in the PyPI has its own software license.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

“What licenses do most PyPI packages have?”

A

“Most of the packages (especially the popular ones) have free or open source licenses (see opensource.org for details).”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

“Do licenses allow including modules in programs?”

A

“In most cases

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

“What to do when in doubt about licenses?”

A

“When in doubt

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

“What happens building larger programs?”

A

“Building larger and more complex programs often leads you to rely on various packages from the Python community.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

“What command-line tool installs packages?”

A

“You’ll find yourself running the python3 -m pip command-line tool to install packages like pytz

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

“Where does pip install packages by default?”

A

“The problem is that

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

“What does global installation cause?”

A

“That causes all Python programs on your system to be affected by these installed modules.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

“In theory

A

is this an issue?”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

“What are transitive dependencies?”

A

“The trouble comes from transitive dependencies (the packages that the packages you install depend on).”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
“When can dependency conflicts arise?”
“A dependency conflict can arise as 2 packages diverge over time.”
26
“What if packages require same dependency version?”
“Perhaps the 2 packages both require the same version of the same dependency
27
“What might happen months from now?”
“But several months from now
28
“What happens updating global package version?”
“If you update your global version of that package with python3 -m pip install –upgrade package
29
“What causes breakage when updating packages?”
“The cause of a breakage mentioned above is that Python can only have a single global version of a module installed at a time.”
30
“What if packages need different versions?”
“If one of your installed packages must use the new version and another has to use the old version
31
“What is dependency hell?”
“This is called dependency hell.”
32
“Can breakage happen with API compatibility?”
“Such breakage can even happen when package maintainers try their best to preserve API compatibility between releases.”
33
“Can new versions subtly change behaviors?”
“New versions of a library can subtly change behaviors that API-consuming code relies on.”
34
“What if users upgrade selectively?”
“Users on a system may upgrade one package to a new version but not others
35
“What’s the constant risk with dependencies?”
“If you’re not careful there’s a constant risk of the ground moving beneath your feet.”
36
“Are difficulties magnified when collaborating?”
“These difficulties are magnified when you collaborate with other developers who do their work on separate computers.”
37
“What to assume about other developers’ machines?”
“It’s best to assume worst: that the versions of Python and global packages that they have installed on their machines will be slightly different from yours.”
38
“What frustrating situations can occur?”
“This can cause frustrating situations such as a codebase working perfectly on one programmer’s machine and being completely broken on others.”
39
“What’s the solution to dependency problems?”
“The solution to all these problems is using a tool called venv
40
“Since when are pip and venv available?”
“Since Python 3.4
41
“What does venv allow?”
“venv allows you to create isolated versions of the Python environment.”
42
“Can you have different package versions?”
“Using venv
43
“What does this mean for projects?”
“This means that you can work on many different projects and use many different tools on the same computer.”
44
“How does venv accomplish isolation?”
“venv does this by installing explicit versions of packages and their dependencies into completely separate directory structures.”
45
“What does this make possible?”
“This makes it possible to reproduce a Python environment that you know will work with your code.”
46
“Is venv reliable for avoiding breakages?”
“It’s a reliable way to avoid surprising breakages.”
47
“What should you know before using venv?”
“Before you use the following information
48
“What’s important about Python on your system?”
“It’s important to know where Python is located and what version of Python you have on your behavior.”
49
“Where must each virtual environment live?”
“Each virtual environment must live in its own directory.”
50
“What results from each environment’s directory?”
“The result of this is a tree of directories and files that are used to manage the virtual environment.”
51
“How to start a virtual environment?”
“To start the virtual environment
52
“What does activate modify?”
“activate modifies all of your environmental variables to match the virtual environment.”
53
“What else does activate update?”
“It also updated your command-line prompt to include the virtual environment name to make it clear what you’re working on.”
54
“What’s the Windows activate script?”
“On Windows the same script is available as activate.bat or activate.ps1 (with Powershell).”
55
“What happens to python3 path after activation?”
“After activation
56
“Why does the path change?”
“This happens to make sure that changes to the outside system won’t affect the virtual environment.”
57
“What if outer system upgrades Python?”
“Even if the outer system upgrades its Python version
58
“What tools do new environments start with?”
“New virtual environments start with no tools except pip and setuptools.”
59
“How to verify packages are working?”
“You can verify that packages are working by using a test import command: python3 -c ‘import pytz’.”
60
“What command when done with environment?”
“When you’re done with a virtual environment and want to go back to a default system
61
“What does deactivate do?”
“This restores your environment to the system defaults
62
“How to work in project’s environment again?”
“If you ever want to work in a project’s environment again
63
“Can you install packages in virtual environment?”
“Once you are in a virtual environment
64
“What might you want to do eventually?”
“Eventually
65
“Does venv make copying easy?”
“venv makes the task mentioned above easy.”
66
“What command saves package dependencies?”
“You can use python3 -m pip freeze to save all your explicit package dependencies into a file (which is named requirements.txt by convention).”
67
“How to install from requirements?”
“You can install the packages from one virtual environment in another environment by using python3 -m pip install.”
68
“Is requirements.txt ideal for collaboration?”
“Using requirements.txt is ideal for collaborating with others through a revision control system.”
69
“What can you commit together?”
“You can commit changes to your code at the same time you update your list of package dependencies
70
“Is Python version in requirements.txt?”
“However
71
“What’s the gotcha with virtual environments?”
“The gotcha with virtual environments is that moving them breaks everything because all of the paths
72
“Does the limitation matter?”
“But ultimately this limitation doesn’t matter.”
73
“What’s the purpose of virtual environments?”
“The whole purpose of virtual environments is to make it easy to reproduce a setup.”
74
“What instead of moving venv directory?”
“Instead of moving a virtual environment directory
75
“Why is documentation extremely important?”
“Documentation in Python is extremely important because of the dynamic nature of the language.”
76
“Does Python support attaching documentation?”
“Python provides built-in support for attaching documentation to blocks of code.”
77
“Is documentation accessible at runtime?”
“Unlike with many other languages
78
“How to add documentation to a function?”
“You can add documentation to a function by adding a docstring immediately after the def statement.”
79
“How to retrieve a function’s docstring?”
“You can retrieve a function’s docstring by accessing its **doc** special attribute.”
80
“What can pydoc module do?”
“You can also use the pydoc module from the command line to run a local web server that hosts all of the Python documentation that accessible to your interpreter
81
“What can docstrings attach to?”
“Docstrings can be attached to functions
82
“Is this part of compilation process?”
“This connection is part of the process of compiling and running the a Python program.”
83
“How many consequences of docstring support?”
“Support for docstrings and the **doc** attribute has 3 consequences.”
84
“What’s the first docstring consequence?”
“The accessibility of documentation makes interactive development easier. You can inspect functions
85
“What’s the second docstring consequence?”
“A standard way of defining documentation makes it easy to build tools that convert the text into more appealing formats (like HTML). This has led to excellent documentation tools for the Python community
86
“What’s the third docstring consequence?”
“Python’s first-class
87
“How to participate in documentation culture?”
“To participate in this excellent culture of documentation
88
“Where are docstring details discussed?”
“The full details are discussed online in PEP 257.”
89
“Are there best practices for docstrings?”
“There are a few best practices you should be sure to follow.”
90
“Should modules have top-level docstrings?”
“Each module should have a top-level docstring (a string literal that is the first statement in a source file).”
91
“What should module docstring use?”
“It should use 3 double quoted """.”
92
“What’s the goal of module docstring?”
“The goal of the docstring is to introduce the module and its contents.”
93
“What should first sentence of module docstring be?”
“The first sentence should be a single sentence describing the module’s purpose.”
94
“What should following paragraphs contain?”
“The paragraphs that follow should contain the details that all users of the module should know about its operation.”
95
“What else is module docstring for?”
“The module docstring is also a jumping-off point where you can highlight important classes and functions found in the module.”
96
“What if module is command-line utility?”
“If the module is a command-line utility
97
“Should classes have class-level docstrings?”
“Each class should have a class-level docstring.”
98
“Does class docstring follow same pattern?”
“This largely follows the same pattern as the module-level docstring.”
99
“What should first line of class docstring be?”
“The first line is a single-sentence purpose of the class.”
100
“What do following paragraphs discuss?”
“Paragraphs that follow discuss important details of the class’s operation.”
101
“What should be highlighted in class docstring?”
“Important public attributes and methods of the class should be highlighted in the class-level docstring.”
102
“What guidance should class docstring provide?”
“It should also provide guidance to sub-classes on how to properly interact with protected attributes and the superclass’s methods.”
103
“Should functions have docstrings?”
“Each public function and method should have a docstring.”
104
“Does function docstring follow same pattern?”
“This follows the same pattern as the docstrings for modules and classes.”
105
“What should first line of function docstring be?”
“The first line is a single-sentence description of what the function does.”
106
“What should following paragraphs describe?”
“The paragraphs that follow should describe any specific behaviors and the arguments for the functions.”
107
“What else should be mentioned?”
“Any values should be mentioned.”
108
“What about exceptions in docstrings?”
“Any exceptions that callers must handle as part of the function’s interface should be explained.”
109
“What if function has no arguments and simple return?”
“If a function has no arguments and a simple return value
110
“What if function doesn’t return anything?”
“If a function doesn’t return anything
111
“What if function interface includes exceptions?”
“If a function’s interface includes raising exceptions
112
“Should you mention unexpected exceptions?”
“If you don’t expect a function to raise an exception during normal operation
113
“How to document *args and **kwargs?”
“If a function accepts a variable number of arguments
114
“Should default values be mentioned?”
“If a function has arguments with default values
115
“What should generator docstring describe?”
“If a function is a generator
116
“What should async coroutine docstring explain?”
“If a function is an asynchronous coroutine
117
“Does Python support type annotations now?”
“Python now supports type annotations for a variety of purposes.”
118
“May type annotations be redundant?”
“The information they contain may be redundant with typical docstrings.”
119
“Need to specify type in docstring with annotations?”
“There is no longer a need to specify the type of an argument in a docstring
120
“Should redundancy be avoided?”
“The redundancy between type annotations and docstrings should be similarly avoided for instance fields
121
“Where best to have type information?”
“It’s best to only have type information in only one place so there’s less risk that it will skew from the actual implementation.”
122
“What’s natural as codebase grows?”
“As the size of a program’s codebase grows
123
“What to do with larger functions?”
“You’ll split larger functions into smaller functions.”
124
“What to do with data structures?”
“You’ll refactor data structures into helper classes.”
125
“What to do with functionality?”
“You’ll separate functionality into various modules that depend on each other.”
126
“What will you need at some point?”
“At some point
127
“What does Python have for this?”
“Python had packages (modules that contain other modules) for this purpose.”
128
“How are packages defined?”
“In most cases
129
“What happens once **init**.py is present?”
“Once **init**.py is present
130
“How to import module from package?”
“To import a module
131
“Does pattern continue for nested packages?”
“This pattern continues when you have package directories present within other packages (import project.package.module).”
132
“How many primary purposes for packages?”
“The functionality provided by packages has two primary purposes in Python programs.”
133
“What’s first use of packages?”
“The first use of packages is to help divide your modules into separate namespaces.”
134
“What do packages enable?”
“They enable you to have many modules with the same filename but different absolute paths that are unique.”
135
“When does namespace approach break?”
“The approach mentioned above breaks when functions
136
“What’s solution to same-name conflicts?”
“The solution to the problem mentioned above is to use the as clause of the import statement to rename whatever you’ve imported in the current scope.”
137
“What can as clause rename?”
“The as clause can be used to rename anything retrieved with the import statement
138
“What does this facilitate?”
“This facilitates namespaced code and makes its identity clear when you use it.”
139
“What’s another approach for conflicts?”
“Another approach for avoiding imported name conflicts is to always access names by their highest unique module names.”
140
“Can you avoid as clause?”
“The approached mentioned above allows you to avoid the as clause altogether.”
141
“What does this make clear?”
“It also makes it abundantly clear to new readers of the code where each of the similarly defined functions is defined.”
142
“What’s second use of packages?”
“The second use of packages in Python is to provide strict
143
“What to provide for external consumption?”
“When you’re writing an API for external consumption
144
“What’s important for stable APIs?”
“To ensure that happens
145
“Why hide internal code?”
“This way
146
“How limit surface area to API consumers?”
“Python can limit the surface area exposed to API consumers by using the **all** special attribute of a module or package.”
147
“What’s the value of **all**?”
“The value of **all** is a list of every name to export from the module as part of its public API.”
148
“What happens with from module import *?”
“When consuming code executes from module import *
149
“What if **all** isn’t present?”
“If **all** isn’t present
150
“What does providing public parts do?”
“If you want to provide all the public parts of an API as a set of attributes
151
“What does this ensure for API consumers?”
“This makes sure that the API consumer’s code will continue to work even if the internal organization of package changes.”
152
“What to modify for this strategy?”
“To accomplish the strategy mentioned above
153
“What does **init**.py become?”
“This file is what actually becomes the contents of the package module when it’s imported.”
154
“How specify explicit API?”
“Thus
155
“How expose public interface?”
“If you include all your internal modules in **all**
156
“Are internal-only functions available?”
“Internal-only functions won’t be available to API consumers if you use the above strategy because they aren’t present in **all**.”
157
“What else does omission from **all** mean?”
“Being omitted from **all** also means that they aren’t imported by the from package import *.”
158
“Are internal names hidden?”
“The internal names are effectively hidden.”
159
“When does this approach work well?”
“The approach mentioned above works well when it’s important to provide an explicit
160
“When is **all** unnecessary?”
“However
161
“What’s enough for teams?”
“The namespaces provided by packages is usually enough for a team of programmers to collaborate on large amounts of code they control while maintaining reasonable interface boundaries.”
162
“Are from package import class clear?”
“Import statements like from package import class are clear because the source of class is explicitly module.”
163
“Can wildcard imports be useful?”
“Wildcard imports like from package import * can also be useful
164
“Do wildcards make code difficult?”
“However
165
“What does from module import * hide?”
“from module import * hides the source of names from new readers of the code. If a module has multiple import * statements
166
“What will import * statements do?”
“Names from import * statements will override any conflicting names within the containing module. This can lead to strange bugs by accidental interactions between your code and overlapping names from multiple import * statements.”
167
“What’s safest approach for imports?”
“The safest approach is to avoid import * in your code and explicitly import names with the from package import class.”
168
“What’s a deployment environment?”
“A deployment environment is a configuration in which a program runs.”
169
“How many deployment environments minimum?”
“Every program has at least one deployment environment: the production environment.”
170
“What’s the goal of writing programs?”
“The goal of writing a program in the first place is to put it to work in the production environment and achieve some kind of outcome.”
171
“What does modifying programs require?”
“Writing or modifying a program requires being able to run it on the computer you use for developing.”
172
“May development differ from production?”
“The configuration of your development environment may be very different from that of your production environment.”
173
“Do venv ensure same packages?”
“Tools like venv make it easy to ensure that all environments have the same Python packages installed.”
174
“What’s trouble with production environments?”
“The trouble is that production environments often require many external assumptions that are hard to reproduce in development environments.”
175
“Best way to work around issues?”
“The best way to work around such issues is to override parts of a program at startup time to provide different functionality depending on the deployment environment.”
176
“One way to implement this strategy?”
“One way to implement the strategy mentioned above is to define a constant that indicates which environment you’re using
177
“What’s key part of this strategy?”
“One key part of this is that the code is run in module scope (not inside a function or method) is normal Python code.”
178
“Can you use if at module level?”
“You can use an if statement at the module level to decide how the module will define names.”
179
“What does this make easy?”
“This makes it easy to tailor modules to your various deployment environments.”
180
“What costly assumptions can you avoid?”
“You can avoid having to reproduce costly assumptions like database configurations when they aren’t needed.”
181
“What can you inject for development?”
“You can inject local or fake implementations that ease interactive development
182
“What when configuration gets complicated?”
“When your deployment environment configuration gets really complicated
183
“What does configparser do?”
“Tools like the configparser module lets you maintain production configurations separately from code
184
“Can approach be used for more?”
“The approach detailed above can be used for more than working around external assumptions.”
185
“What else can guide module definitions?”
“You can also use os.environ to guide your module definitions.”
186
“Are exceptions part of module’s API?”
“When you’re defining a module’s API
187
“Does Python have exception hierarchy?”
“Python has a built-in hierarchy of exceptions for the language and the standard library.”
188
“Is there draw to built-in exceptions?”
“There’s a draw to using the built-in exception types for reporting errors instead of defining your own new types.”
189
“Is it powerful to define exception hierarchy?”
“For APIs
190
“How can you define exception hierarchy?”
“You can do this by providing a root Exception in your module and have all other exceptions raised by the module inherit from the root exception.”
191
“What does root exception make easy?”
“Having a root exception in a module makes it easy for consumers of an API to catch all of the exceptions that are raised deliberately.”
192
“What does logging.exception do?”
“The logging.exception function prints a full stack trace of a caught exception so it’s easier to debug.”
193
“How to implement root exception strategy?”
“One way to implement the root exception strategy is to use a try/except statement to catch the root exception (try (code)…. except RootError).”
194
“What does this prevent?”
“This prevents the APIs exceptions from propagating too far upward and breaking the calling program.”
195
“What does it insulate?”
“It insulates the calling code from the API.”
196
“How many helpful effects of insulation?”
“This insulation has 3 helpful effects.”
197
“What’s first effect of root exceptions?”
“First
198
“What should callers do if using API properly?”
“If callers are using someone’s API properly
199
“What if they don’t handle exceptions?”
“If they don’t handle these exceptions
200
“What can that block do?”
“That block can bring the exception to the attention of the API consumer
201
“What’s second advantage of root exceptions?”
“The second advantage of using root exceptions is that they can help find bugs in an API module’s code.”
202
“What if code only raises defined exceptions?”
“If your code only deliberately raises exceptions that you define within your module’s hierarchy
203
“What are unintended exceptions?”
“These are bugs in your API’s code.”
204
“Will try/except insulate from API bugs?”
“Using a try/except statement won’t insulate API consumers from bugs in your API module’s code.”
205
“What to add to insulate from API bugs?”
“To do this
206
“What does this allow detecting?”
“This allows API consumers to detect when there’s a bug in the API module’s implementation that needs to be fixed.”
207
“What’s third benefit of root exceptions?”
“The third benefit of using root exceptions is future-proofing an API.”
208
“What might you want over time?”
“Over time
209
“Will base exception code still work?”
“The code that calls the base exception will still work because it already calls the parent exception.”
210
“How take future-proofing further?”
“You can take the API future-proofing further by providing a broader set of exceptions directly below the root exception.”
211
“What would specific exceptions inherit?”
“Specific exceptions would inherit from a bunch of general exceptions that you create.”
212
“What does each intermediate exception act as?”
“Each intermediate exception acts as its own kind of root exception.”
213
“What does this make easier regarding insulation?”
“This makes it easier to insulate layers of calling code from API code based on broad functionality.”
214
“Is this better than long exception lists?”
“This is better than having the callers catch a long list of Exception subclasses.”
215
“Will you find mutual interdependence?”
“Inevitably
216
“Can this happen working alone?”
“It can even happen while you work by yourself on the various parts of a single program.”
217
“What can cause crash regarding imports?”
“If a module or class imports a module that also imports that class or module (the first one)
218
“What is this called?”
“This is called a circular dependency.”
219
“What to know to understand circular dependencies?”
“To understand circular dependencies
220
“What happens importing module step 1?”
“Python searches for a module in locations from sys.path.”
221
“What happens importing module step 2?”
“Python loads the core of the module and ensures that it compiles.”
222
“What happens importing module step 3?”
“Python creates a corresponding empty module object.”
223
“What happens importing module step 4?”
“Python inserts the module into sys.modules.”
224
“What happens importing module step 5?”
“Python runs the code in the module object to define its contents.”
225
“What’s problem with circular dependencies?”
“The problem with circular dependencies is that the attributes of a module aren’t defined until the code for those attributes has executed (after step 5).”
226
“When can module be loaded with import?”
“But a module can be loaded with import immediately after it’s inserted into sys.modules (after step 4).”
227
“How many ways to break circular dependencies?”
“There are 3 main ways to break circular dependencies.”
228
“What’s first way to break circular dependencies?”
“The first way to break circular dependencies is to change the order of imports.”
229
“Why does this work?”
“This works because
230
“Does this avoid AttributeError?”
“Although this avoids an AttributeError
231
“What does PEP 8 suggest?”
“The guide suggests that you always put imports at the top of your Python files.”
232
“Why put imports at top?”
“This makes your module’s dependencies clear to new readers of the code.”
233
“What else does top imports ensure?”
“It also ensures that any module you depend on is in scope and available to all code in your module.”
234
“Can late imports be brittle?”
“Having imports later in a file can be brittle and can cause small changes in the ordering of your code to break the module entirely.”
235
“Should you use import reordering?”
“You shouldn’t use import reordering to solve your circular dependency issues.”
236
“What’s second solution to circular imports?”
“A second solution to the circular imports problem is to have modules minimize side effects at import time.”
237
“What can your modules have?”
“You can only have your modules define functions
238
“What’s one strategy given constraints?”
“One strategy to combat this given these constraints is to avoid running any functions at import time
239
“What’s purpose of configure?”
“The purpose of configure is to prepare each module’s state by accessing the attributes of other modules.”
240
“When do you run configure?”
“You run configure after all modules have been imported (step 5 is complete)
241
“How many phases does main module have?”
“Lastly
242
“Does this work well?”
“This works well in many situations and enables patterns like dependency injection.”
243
“Can it be difficult to structure?”
“But sometimes it can be difficult to structure your code so that an explicit configure step is possible.”
244
“Can two phases make code harder to read?”
“Having two distinct phases within a module can also make your code harder to read because it separates the definition of objects and their configuration.”
245
“What’s third solution to circular imports?”
“The third (and often simplest) solution to the circular imports problem is to use an import statement within a function or method.”
246
“What is this called?”
“This is called a dynamic import because the module import happens while the program is running
247
“What effect does this have?”
“This approach has a similar effect to the import
248
“What’s the difference?”
“The difference is that it requires no structural changes to the way modules are defined and imported.”
249
“What are you delaying?”
“You’re simply delaying the circular import until the moment you have to access the other module.”
250
“Can you be sure modules are initialized?”
“At that point
251
“Is it good to avoid dynamic imports?”
“In general
252
“What’s the cost of import statement?”
“The cost of the import statement is not negligible and can be especially bad in tight loops.”
253
“What do dynamic imports set you up for?”
“By delaying execution
254
“Is it natural for APIs to change?”
“It’s natural for APIs to change in order to satisfy new requirements that meet formerly unanticipated needs.”
255
“When are API changes straightforward?”
“When an API is small and has few upstream or downstream dependencies
256
“Can one programmer update small API?”
“One programmer can often update a
257
“Can one programmer update small API?”
“One programmer can often update a small API and all of its callers in a single commit.”
258
“What happens as a codebase grows?”
“However
259
“What do you need instead?”
“Instead
260
“How to minimize breakage when changing code?”
“One way to minimize the breakage of code when you change it while encouraging people to use the new code is to use the warnings module.”
261
“What is using warnings?”
“Using warnings is a pragmatic way to inform other programmers that their code needs to be modified due to a change to the underlying library that you depend on.”
262
“What are exceptions vs warnings for?”
“While exceptions are primarily for automated error handling by machines
263
“How to verify code with warnings works?”
“One way to verify that code you add warnings to works is to call the function with the same arguments you did before you modified it
264
“What does warn function’s stacklevel do?”
“warnings’s warn function has the stacklevel parameter
265
“What else does stacklevel make easy?”
“stacklevel also makes it easy to write functions that can issue warnings on behalf of other code
266
“Can you configure warnings behavior?”
“The warnings module let’s you configure what should happen when a warning is encountered.”
267
“What’s one option for warnings?”
“One option is to make all the warnings you raise become errors
268
“When is exception-raising useful?”
“This exception-raising behavior is especially useful for automated tests in order to detect changes in upstream dependencies and fail tests accordingly.”
269
“What’s great about test failures?”
“Using such test failures is a great way to make it clear to the people you collaborate with that they will need to update their code.”
270
“How to apply this policy?”
“You can use the -Werror command-line argument to the Python interpreter or the PYTHONWARNINGS environmental variable to apply this policy.”
271
“What when people aware of deprecation?”
“Once people are aware that code that depends on a deprecated API are aware that they’ll need to do a migration
272
“Does it make sense for warnings to cause errors in production?”
“After a program is deployed in production
273
“What’s better approach for production?”
“A better approach is to replicate warnings into the logging module.”
274
“How to accomplish this?”
“One way to accomplish this by calling the captureWarnings function and configuring the py.warnings logger.”
275
“What does logging warnings ensure?”
“Using logging to capture warnings ensures that any error reporting systems that my program already has in place will also receive notice of important warnings in production.”
276
“When is this especially useful?”
“This can be especially useful if your tests don’t cover every edge case that you might see when the program is undergoing real usage.”
277
“What should API maintainers do?”
“API library maintainers should also write unit tests to verify that warnings are generated under the correct circumstances with clear and actionable messages.”
278
“What can you use catch_warnings for?”
“You can use warnings.catch_warnings as a context manager.”
279
“What does this let you do?”
“This lets you collect the warning messages
280
“Is documentation enough?”
“Providing documentation is a great way to help users of an API understand how to use it properly
281
“What would be ideal?”
“Ideally
282
“How do many languages address this?”
“Many programming languages address part of this need with compile-time type checking
283
“Has Python historically provided compile-time type safety?”
“Historically Python has focused on dynamic features and has not provided compile-time type safety of any kind.”
284
“What has Python introduced recently?”
“However
285
“What do type hints allow?”
“These type hints allow for gradual typing (where a codebase can be incrementally updated to specify types as desired).”
286
“What’s benefit of adding type information?”
“The benefit of adding type information to a Python program is that you can run static analysis tools to ingest a program’s source code and identify where bugs are most likely to occur.”
287
“Does typing module implement type checking?”
“The typing module doesn’t actually implement any of the type checking functionality itself.”
288
“What does typing module provide?”
“It merely provides a common library for defining types
289
“Are there multiple static analysis tools?”
“Much as there are multiple distinct implementations of the Python implementation (e.g. CPython
290
“What are most popular tools?”
“At the time of this writing
291
“What does mypy with –strict flag do?”
“mypy with the —strict flag enables all the various warnings that are supported by the tool.”
292
“What can these tools detect?”
“Tools like the one mentioned above can be used to detect a large number of common errors before a program is ever run
293
“How are parameter annotations delineated?”
“Parameter and variable type annotations are delineated with a colon (such as name: type).”
294
“How are return values specified?”
“Return values are specified with -> type following the argument list.”
295
“What’s a common mistake?”
“A common mistake (especially for programmers who have moved from Python 2 to Python 3) is mixing byte and str instances together.”
296
“Can typing issues be detected statically?”
“Typing issues can be detected statically before a program runs using type hints and mypy.”
297
“Can type annotations apply to classes?”
“Type annotations can also be applied to classes.”
298
“What’s one strength of Python’s dynamism?”
“One of the strengths of Python’s dynamism is the ability to write generic functionality that operates on duck types.”
299
“What does this allow?”
“This allows one implementation to accept a wide variety of types
300
“Can you annotate generic functions?”
“You can use the typing module’s support for generics to annotate functions and detect problems statically.”
301
“What’s another very common error?”
“Another very common error is to encounter a None value when you thought you’d have a valid object.”
302
“Can this affect simple code?”
“This problem can affect seemingly simple code.”
303
“What does typing support for None?”
“typing supports option types
304
“Are other options available in typing?”
“A wide variety of other options are available in the typing module.”
305
“Are exceptions included in typing?”
“Notably
306
“How does Python differ from Java regarding exceptions?”
“Unlike Java
307
“How to verify exception handling?”
“Thus
308
“What’s one common gotcha in typing?”
“One common gotcha in using the typing module occurs when you need to deal with forward references.”
309
“Can you trigger circular dependency issues with type annotations?”
“You can trigger circular dependency issues if a class is referenced in the type annotations of another class before it’s actually defined.”
310
“What’s one workaround for forward references?”
“One workaround to avoid the problem mentioned above that is supported by these static analysis tools is to use a string as the type annotation that contains the forward reference.”
311
“How is string value used for forward references?”
“The string value is later parsed and evaluated to extract the type information to check.”
312
“What’s a better approach for forward references?”
“A better approach is to use from **future** import annotations
313
“What does **future** import annotations instruct?”
“This instructs the Python interpreter to completely ignore the values supplied in type annotations when the program is being run.”
314
“What does this resolve?”
“This resolves the forward reference problem and provides a performance improvement at program start time.”
315
“Should you be thoughtful about using type hints?”
“Now that you’ve seen how to use type hints and their potential benefits
316
“Will type annotations slow you down initially?”
“It’s going to slow you down if you try to use type annotations from the start when writing a new piece of code. A general strategy is to write a first version without annotations
317
“Where are type hints most important?”
“Type hints are most important at the boundaries of your codebase
318
“Can type hints be useful for complex code?”
“It can be useful to apply type hints to the most complex and error-prone parts of your codebase that aren’t part of an API. However
319
“Should you include static analysis in build system?”
“If possible
320
“Should you run type checker as you go?”
“As you add type information to your code
321
“May you not need type annotations?”
“Finally
322
“When may type hints require too much effort?”
“For small programs