# Import
By 極速車神大佬 - 楊翔宇
---
## 為什麼要 import?
----
我們目前寫的程式都是放在同一個檔案裡面,
大概想的到:不太可能到如果是一個系統也這麼做
----
事實上...
----
這是學界常用的機器學習函式庫, Pytorch

----
這是 Sprout OJ 的原始專案

----
都是很多層資料夾、很多個檔案組成的專案!
如果覺得很恐怖也沒關係,畢竟這是幾千個人一起開發的專案XD
---
## 什麼是 module?
module 就是 Python 的一個檔案,裡面可以定義 function, class, 變數等等,可以是:
- Python 的內建 module (例如 math, random)
- 第三方 module (例如 pytorch, pandas)
- 自己寫的 module (例如 my_module.py)
---
## import 的語法
我們先以內建 module 為範例
----
### Type 1
```python
import math
print(math.sqrt(16)) # 輸出 4.0
```
----
### Type 2
```python
from math import sqrt
print(sqrt(16)) # 輸出 4.0
```
----
或是可以取個別名
```python
from math import sqrt as sqr
print(sqr(16)) # 輸出 4.0
```
----
有些第三方 module 會有約定俗成的名字
```python
import numpy as np
print(np.sqrt(16)) # 輸出 4.0
```
----
### Type 3
```python
from math import *
print(sqrt(16)) # 輸出 4.0
```
但不推薦這樣做,因為可能會有多個 function/class 的名稱一樣,會造成衝突
---
## 常用的 module
----
- 內建的
- math: 數學相關的 module
- random: 亂數相關的 module
- datetime: 日期時間相關的 module
- os: 作業系統相關的 module
- 第三方的
- numpy: 數學計算相關的 module
- pandas: 資料分析相關的 module
- matplotlib: 資料視覺化相關的 module
- pytorch: 機器學習相關的 module
- tensorflow: 機器學習相關的 module
- ... 還有很多
這邊先介紹內建的,第三方的 module 以後在二階會有更多介紹!
----
### math
```python
import math
print(math.sqrt(16)) # 輸出 4.0
print(math.pi) # 輸出 3.141592653589793
print(math.sin(math.pi / 2)) # 輸出 1.0
```
----
### random
```python
import random
print(random.random()) # 輸出 0.0 ~ 1.0
print(random.randint(1, 10)) # 輸出 1 ~ 10 的整數
print(random.choice(['apple', 'banana', 'cherry'])) # 從 list 中隨機選擇一個元素
```
----
### datetime
```python
import datetime
now = datetime.datetime.now() # 取得現在的日期時間
print(now) # 輸出 2024-06-01 12:00:00.000000
print(now.year) # 輸出 2024
print(now.month) # 輸出 6
print(now.day) # 輸出 1
```
----
### os
```python
import os
print(os.getcwd()) # 輸出目前的工作目錄
print(os.listdir()) # 輸出目前目錄下的檔案和資料夾
```
---
## 自己寫一個 module!
自己寫一個 module 包含四則運算
檔案架構:
```
my_module/
├── main.py
└── calculation.py
```
----
`calculation.py`
```python
def add(a, b):
return a + b
```
`main.py`
```python
from calculation import add
# import calculation # 這樣寫的話就要寫 calculation.add(1, 2)
# from calculation import * # 也可以這樣寫,但不推薦
print(add(1, 2)) # 輸出 3
```
----

----
現在練習一下!
----
但是我們可能要 import 的檔案在不同資料夾下...
---
## Python 到底怎麼找到你要 import 的東西?
Python 在執行 `import xxx` 時,會去一個清單裡面「由上到下」找有沒有叫做 `xxx` 的 module。
1. 當前目錄
2. PYTHONPATH
3. sys.path
----
可以印出來看看:
```python
import sys
print(sys.path)
```
----
### 不同資料夾怎麼 import?
如果檔案格式長這樣,而你想從 `main.py` 去 import `calculation.py` 裡的東西:
```
sprout/
├── main.py
└── my_module/
└── calculation.py
```
----
可以在 `main.py`(專案根目錄)寫:
這時候其實資料夾 `my_module` 就是一個 module
```python
from my_module.calculation import add
print(add(1, 2))
```
---
## 結語:
import 是一個很強大的工具!
之後二階使用第三方 module 會很常很常用到!
---
## import 其實可以拿到「變數」!
前面說 module 裡可以放 function。
`import` 當然也可以把 **module 裡定義的變數** 拿出來用。
----
例如 `calculation.py` 裡有:
```python
PI = 3.14159
def add(a, b):
return a + b
```
你就可以:
```python
import my_module
print(my_module.calculation.PI)
```
----
也可以整個 module 匯入再用點號存取:
```python
import my_module.calculation as calc
print(calc.PI)
print(calc.add(1, 2))
```
----
事實上,之前講過兩種 import 方式原理不太一樣:
- `import my_module` 你在當前檔案建立了一個名為 `my_module` 的標籤,指向 `my_module` module 物件。存取時使用 my_module.calculation.PI,這是直接去找值。
- `from my_module.calculation import add` 是建立一個名為 `add` 的標籤,並讓它指向 `my_module.calculation` 模組中 `add` 所指向的那個記憶體位址。
----
如果 `my_module` 裡面的內容會變的話,建議用 `import my_module` 的方式,這樣如果 `my_module` 裡面的內容有變動,你在當前檔案裡面存取的值也會跟著變動。
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Noto+Sans+TC:wght@100..900&display=swap');
:root {
--r-code-font: "JetBrains Mono", monospace;
--r-main-font: "Inter", "Noto Sans TC", sans-serif;
--r-heading-font: "Inter", "Noto Sans TC", sans-serif;
--r-heading-text-transform: none;
--r-main-font-size: 32px;
}
.reveal-viewport {
backdrop-filter: blur(64px);
background:
radial-gradient(circle at top left, #3398, #0000 50%),
radial-gradient(circle at bottom right, #9938, #0000 50%),
#000d;
}
.reveal .slides {
text-align: left;
}
.reveal .slides .slide:not(.title-slide) {
height: 80%;
}
.reveal .slides .slide .slide-body {
height: 80%;
display: flex;
flex-direction: column;
justify-content: center;
}
.reveal div.sourceCode {
margin: 0;
min-height: 0;
background: transparent;
display: flex;
flex-direction: column;
}
.reveal pre {
all: unset;
min-height: 0;
display: flex;
flex-direction: column;
}
.reveal code {
font-size: .8em;
padding: .2em;
border: 1px solid #fff3;
border-radius: .2em;
background-color: #0003;
}
.reveal .sourceCode code {
font-size: .6em;
padding: 1em;
overflow: scroll;
}
.reveal blockquote {
display: flex;
flex-direction: column;
background: transparent;
box-shadow: none;
}
.reveal blockquote p {
margin: 0;
}
.reveal blockquote::before {
content: "❝";
font-size: 2em;
line-height: 0;
margin-left: -1em;
margin-bottom: -.25em;
}
.reveal blockquote::after {
content: "❞";
font-size: 2em;
line-height: 0;
text-align: right;
}
.reveal blockquote + p {
text-align: right;
}
</style>
{"title":"Import","description":"我們目前寫的程式都是放在同一個檔案裡面,大概想的到不太可能到如果是一個系統也這麼做事實上…","contributors":"[{\"id\":\"6a375517-4167-4b7c-a983-1e595a29262c\",\"add\":5737,\"del\":176,\"latestUpdatedAt\":1774089876548}]"}