Skip to content
This repository was archived by the owner on Dec 31, 2025. It is now read-only.

Commit ad6a2e3

Browse files
committed
add python module section
1 parent 5e46670 commit ad6a2e3

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

book/extras.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
- discuss Naur, "Programming as theory building"
44

5+
## for essentials
6+
7+
- discuss databases - e.g. sqlite example
8+
9+
510
## from AI-assisted coding chapter
611

712
## github spec kit
@@ -20,3 +25,74 @@ The ability to LLMs to write code to solve problems provides a solution to the r
2025

2126
For example, ...
2227

28+
# Project structure
29+
30+
31+
## Python modules
32+
33+
While Python has native access to a small number of functions, much of the functionality of Python comes from *modules*, which provide access to objects defined in separate files that can be imported into a Python session. All Python users will be familiar with importing functions from standard libraries (such as `os` or `math`) or external packages (such as `numpy` or `pytorch`). It's also possible to create one's own modules simply by putting functions into a file.
34+
35+
Let's say that we have a set of functions that do specific operations on text, saved to a file called `textfuncs.py` in our working directory:
36+
37+
```
38+
def reverse(text):
39+
return text[::-1]
40+
41+
def capitalize(text):
42+
return text.capitalize()
43+
44+
def lowercase(text):
45+
return text.lower()
46+
```
47+
48+
If we wish to use those functions within another script ('mytext.py'), we can simply import the module and then run them:
49+
50+
```
51+
import textfuncs
52+
53+
def main():
54+
mytext = "Hello World"
55+
print(mytext)
56+
print(textfuncs.reverse(mytext))
57+
print(textfuncs.capitalize(mytext))
58+
print(textfuncs.lowercase(mytext))
59+
60+
if __name__ == "__main__":
61+
main()
62+
```
63+
64+
Giving the results:
65+
66+
```
67+
❯ python mytext.py
68+
Hello World
69+
dlroW olleH
70+
Hello world
71+
hello world
72+
```
73+
74+
```{admonition} Antipattern
75+
It's not uncommon to see Python programmers use *wildcard imports*, such as `from mytext import *`. This practice is an antipattern and should be avoided, because it can make it very difficult to debug problems with imported functions, particularly if there is a wildcard import from more than one module. It can also result in collisions if two modules have a function with the same name, and can prevent linters from properly analyzing the code. It's better practice to explicitly import all objects from a module, or to use fully specified paths within the module.
76+
77+
R users might notice that this antipattern is built into the way that library functions are usually imported in R: In general, when one imports a library the functions are made available directly in the global namespace. For example, if we load the `dplyr` library we will see several errors regarding objects being masked:
78+
79+
````
80+
> library(dplyr)
81+
82+
Attaching package: ‘dplyr’
83+
84+
The following objects are masked from ‘package:stats’:
85+
86+
filter, lag
87+
88+
The following objects are masked from ‘package:base’:
89+
90+
intersect, setdiff, setequal, union
91+
````
92+
93+
This means that if we call `filter()` it will now refer to `dplyr::filter()` rather than the default reference to `stats::filter()`. This can cause major problems when one adds library imports during the development process, since those later additions can mask functions that had worked without disambiguation before. For this reason, when coding in R it's always good to use the full disambiguated function call for any functions with generic names like "select" or "filter".
94+
95+
```
96+
97+
### Creating a Python module using uv
98+

0 commit comments

Comments
 (0)