資訊之芽 2022 Python 語法班
Author: Sean 韋詠祥
# 語法結構
import <模組名稱>
# 舉個例子 🌰
import math
x = math.floor(3.14)
print(x)
# 語法結構
from <模組> import <模組內的東西>
from <模組> import <子模組>, <函式>, <常數>, <Class>
# 舉個例子 🌰
from string import hexdigits, capwords
print(hexdigits)
print(capwords('hello woRLD'))
# 語法結構
from <模組> import *
# 舉個例子 🌰
from math import * # 裡面包含 floor, gcd, pi 等函式及變數
n = floor(9 * pi)
print('n =', n)
m = gcd(n, 35)
print('m =', m)
# 語法結構
import <模組> as <別名>
from <模組> import <東西> as <別名>
# 舉個例子 🌰
import unicodedata as ud
from math import factorial as fact
print('Name 1:', ud.name('!')) # EXCLAMATION MARK
print('Name 2:', ud.name('😼')) # CAT FACE WITH WRY SMILE
print('5! = ', fact(5))
用 Python 計算以下數值
\[ 3^5 \text{ = ?} \\ \sqrt{2} \text{ = ?} \\ \cos (\frac{\pi}{3}) \text{ = ?} \]
Hint: 全部在 math 裡面
sqrt, cos, pow, pi
建立一個名為 fibo.py
的模組檔案
# File: fibo.py def fib(n): a, b = 0, 1 while a < n: print(a, end=' ') a, b = b, a+b print()
在 VS Code 中,請按 ^N (Ctrl-N) 新增檔案
寫完後用 ^S 存檔
import fibo # 前面 fibo.py 檔名,拿掉 .py fibo.fib(20)
from fibo import fib fib(20)
在 VS Code 中,點右上角 ▷ 執行程式
在 sprout.py
中,自己定義 fact()
函式
fact(0) = 1
fact(1) = 1 # 1
fact(2) = 2 # 2 * 1
fact(3) = 6 # 3 * 2 * 1
fact(4) = 24 # 4 * 3 * 2 * 1
fact(5) = 120 # 5 * 4 * 3 * 2 * 1
fact(6) = 720 # 6 * 5 * 4 * 3 * 2 * 1
....
fact(15) = 1307674368000 # 15 * 14 * 13 * ... * 2 * 1
Hint: 可以在 def fact()
中遞迴呼叫 fact()
函式
當有一些函式不希望被 import *
進來
# File: sprout.py __all__ = ['fact'] def is_negative(n): if n < 0: return True return False def fact(n): if is_negative(n): return -1 # Error! if n > 1: return n * fact(n-1) return 1
在 from sprout import *
的時候,只有 __all__
裡面寫到的 fact
會被 import 進來
Note. 但可以被 import sprout
或 from sprout import is_negative
取用
在模組中,還有可以加上…
__author__ = 'Sean Wei'
__version__ = '1.19.2'
__license__ = 'MIT'
__status__ = 'Production'
__email__ = 'me@sean.taipei'
__copyright__ = 'Copyright 2022, Sprout Team'
import math
print('gcd:', math.gcd(52, 91)) # 最大公因數
print('lcm:', math.lcm(15, 21)) # 最小公倍數
print('ceil:', math.ceil(4.2)) # 上高斯(無條件進位)
print('floor:', math.floor(4.2)) # 下高斯(無條件捨去)
# 前面是函式,這兩個沒有括號的是常數
print('Natural number:', math.e) # 自然數
print('Pi:', math.pi) # 圓周率 π
import string
# 小寫字母:abcdefghijklmnopqrstuvwxyz
print('Lowercase:', string.ascii_lowercase)
# 標點符號:!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~
print('Punctuation:', string.punctuation)
# 可視字元:
print('Printable:', string.printable)
# 0123456789abcdefghijklmnopqrstuvwxyz
# ABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()
# *+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c
import random
# 在 [0, 1) 之間的浮點數
print('Random number:', random.random())
# 在 [1, 5] 之間挑選一個整數
print('Lucky number:', random.randint(1, 5))
# 在 [20, 80) 之間挑選一個浮點數
print('Precipitation:', random.uniform(20, 80))
# 產生內容為 [0, 1, 2, ... 48, 49] 的 list
A = [i for i in range(50)]
print('The list A:', A)
# 在 list 中隨機選一個值
print('Choice one:', random.choice(A))
random.shuffle(A) # 把 A 的順序打亂
print('After shuffle:', A) # 現在 A 被原地修改為新的順序了
import os
# 取得目前目錄路徑
print('Current working directory:', os.getcwd())
# 列出目錄中檔案,以根目錄為例
print('Files:', os.listdir('/'))
# 建立資料夾
os.mkdir('tmp-py2022-data')
# 移除檔案
os.remove('trash-file')
import sys
# 執行的參數列表
print('Arguments:', sys.argv)
# 套件路徑列表
print('Python Path:', sys.path)
# 版本資訊:3.9.12 (main, Mar 26 2022) [Clang 13.1.6]
print('Version:', sys.version)
import time
# 目前秒數:1650177060
print('Time 1:', time.time())
# 中間暫停 1.5 秒
time.sleep(1.5)
# 會比上面的秒數多 1.5 秒
print('Time 2:', time.time())
from datetime import datetime
# 結構化的目前時間:datetime(2022, 4, 17, 14, 55, 20, 123456)
t = datetime.now()
print('Datetime:', repr(t))
# 將時間格式化成指定格式:Sun, 17 Apr 2022
print('Format:', t.strftime('%a, %d %b %Y'))
# 矩陣運算
import numpy as np
# 影像處理
import pillow as pil
# 聊天機器人
import discord as dc
# 網頁內容請求
import requests as req
# 網頁爬蟲
import bs4.BeautifulSoup as bs
# 資料視覺化
import matplotlib.pyplot as plt
# Base64 編碼、解碼
import base64.b64encode as b64e
import base64.b64decode as b64d
第 1 行輸入數字 N 代表長度(N ≥ 5)
第 2 行輸入 0 或 1,代表是否要包含大小寫字母
第 3 行輸入 0 或 1,代表是否要包含數字和標點符號
保證第 2 3 行不會同時為 0
使用前面提到的 strings
及 random
函式庫
每次產生 5 個長度為 N 且符合要求的隨機字串
(就算輸入要求有數字,輸出也可以不出現數字,
只要正常隨機就好)
拆成幾十個模組怎麼辦?
總不能全部丟在同個目錄吧
一個專案可能長得像這樣
discord/ 專案頂層目錄
├── __init__.py ├── 初始化 discord 模組的腳本
├── commands/ ├── 指令相關模組
│ ├── __init__.py │
│ ├── options.py │
│ ├── context.py │
│ └── core.py │
├── utils.py │
├── types/ ├── 專案內用到的自定義型別
│ ├── __init__.py │
│ ├── emoji.py │
│ ├── role.py │
│ └── user.py │
└── ui/ └── 介面相關程式碼
├── __init__.py
├── button.py
└── modal.py
我們可以 import 一個 .py 檔案,那資料夾呢?
因此只有包含 __init__.py
的資料夾可以被引入
此檔案中會放初始化模組用的程式碼
並且用 __all__
特殊變數,指定同目錄下要引入哪些檔案或子資料夾
# File: discord/commands/core.py import request from discord.ui import modal # /ui/modal.py # 以下使用相對名稱 import import ..utils # /utils.py from . import options # /commands/options.py from .context import response # /commands/context.py:response from ..types import user # /types/user.py from ..types.role import color # /types/role.py:color
找不到這個變數
base64.b64decode('U3Byb3V0IDIwMjI=')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'base64' is not defined
確定有 import 相關模組
import <缺少的模組>
import base64
找不到這個模組
import discord
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'discord'
使用 pip 安裝相應套件
$ pip install <缺少的套件>
C:\Users\sean> pip
'pip' is not recognized as an internal or external command,
operable program or batch file.
到 Python 官網安裝
先上程式碼
# File: math.py import math print(math.gcd(42, 18))
錯誤訊息
Traceback (most recent call last):
File ".../math.py", line 1, in <module>
import math
File ".../math.py", line 3, in <module>
print(math.gcd(4, 6))
AttributeError: partially initialized module 'math' has no
attribute 'gcd' (most likely due to a circular import)
為什麼呢?
# File: main.py from foo import func1 func1()
# File: foo.py | # File: bar.py from bar import func2 | from foo import func3 def func1(): | def func2(): func2() | print('Hey there!') def func3(): | func3() print('Goodbye~') |
Traceback (most recent call last):
File ".../main.py", line 1, in <module>
from foo import func1
File ".../foo.py", line 1, in <module>
from bar import func2
File ".../bar.py", line 1, in <module>
from foo import func3
ImportError: cannot import name 'func3' from
partially initialized module 'foo' (most likely
due to a circular import) (.../foo.py)
很重要但下週才會教的 Coding Style
# ✅ 正確寫法
import os
import sys
# ❌ 錯誤示範
import sys, os
# ✅ 這樣也是正確的
from subprocess import Popen, PIPE
#!/usr/bin/env python
"""Script for sprout demo
Meow meow meow meow meow
"""
import os
import math
_USAGE = 'Just run this script. :)'
import os
import string
from time import sleep
from datetime import datetime
import discord
import requests as req
from discord.ext import commands
import sproututils
__future__
等特殊 import"""This is the example module.
This module does stuff.
"""
from __future__ import annotations
__all__ = ['fact', 'exgcd', 'c']
__version__ = '0.1'
__author__ = 'Sprout 2022 Team'
import os
import sys
import datetime
t = datetime.datetime.now()
print('Case A:', t)
print('Case B:', str(t))
print('Case C:', repr(t))
s = repr(t) # 取得給直譯器看的 representation 格式
type(s) # 確認得到的是個字串 (str)
n = eval(s) # 把 str 轉換回 datetime
type(n) # 確認轉換成功
投影片連結:https://hackmd.io/@Sean64/py-module-sprout2022
import __hello__
# Hello world!
import this
# The Zen of Python, by Tim Peters
#
# Beautiful is better than ugly.
# Explicit is better than implicit.
# Simple is better than complex.
# Complex is better than complicated.
# [...]
from __future__ import braces
# SyntaxError: not a chance
# xkcd
import antigravity
# Geohashing: https://xkcd.com/426/
antigravity.geohash(24.787, 120.997, b'Meow')