目標
- 以兩個 datetime 字串為起點
- 解析成 datetime 物件
- 計算時間差與秒數、分鐘數
- 展示「屬性派」與「方法派」都能完成相同任務
- 補充如何正確分辨屬性與方法
先從時間字串開始
start_datetime_str = "2024-02-15 09:18:38.1234"
end_datetime_str = "2024-02-15 09:20:38.1234"
解析成 datetime
from datetime import datetime
fmt = "%Y-%m-%d %H:%M:%S.%f"
start_dt = datetime.strptime(start_datetime_str, fmt)
end_dt = datetime.strptime(end_datetime_str, fmt)
print(start_dt)
print(end_dt)
計算時間差:得到 timedelta
delta = end_dt - start_dt
print(delta) # 0:02:00
print(type(delta)) # <class 'datetime.timedelta'>
輸出結果:

dir()可以列出物件的所有屬性/方法,
但無法區分那一個是屬性,那一個是方法
dir(delta)
"""
['__abs__',
'__add__',
'__bool__',
'__class__',
'__delattr__',
'__dir__',
'__divmod__',
'__doc__',
'__eq__',
'__floordiv__',
'__format__',
'__ge__',
'__getattribute__',
'__getstate__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__mod__',
'__mul__',
'__ne__',
'__neg__',
'__new__',
'__pos__',
'__radd__',
'__rdivmod__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rfloordiv__',
'__rmod__',
'__rmul__',
'__rsub__',
'__rtruediv__',
'__setattr__',
'__sizeof__',
'__str__',
'__sub__',
'__subclasshook__',
'__truediv__',
'days',
'max',
'microseconds',
'min',
'resolution',
'seconds',
'total_seconds']
"""
- 屬性派:用屬性讀數值
timedelta 內建三個主要資料屬性(不需括號):
- days
- seconds
- microseconds
# 屬性派
minutes_via_attrs = (delta.days * 24 * 3600 + delta.seconds + delta.microseconds/1_000_000) / 60
seconds_via_attrs = delta.days * 24 * 3600 + delta.seconds + delta.microseconds/1_000_000
print(minutes_via_attrs) # 2.0
print(seconds_via_attrs) # 120.0
說明
- timedelta 的內部以天、秒、微秒三部分表達;自行組合就能得出任意單位。
- 優點:不依賴額外方法,邏輯透明。
- 缺點:容易手誤,重複性高。
- 方法派:用方法拿總秒數
timedelta 提供方法 total_seconds(),直接回傳整體秒數(含小數)。
# 方法派
seconds_via_method = delta.total_seconds()
minutes_via_method = seconds_via_method / 60
print(seconds_via_method) # 120.0
print(minutes_via_method) # 2.0
說明
- 優點:簡潔、可讀性高。
- 缺點:依賴該方法存在;若是自訂類型需自行實作。
- 兩派結果一致性檢查
assert abs(seconds_via_attrs - seconds_via_method) < 1e-9
assert abs(minutes_via_attrs - minutes_via_method) < 1e-9
print("屬性派與方法派的結果一致。")
- 如何分辨屬性與方法(正確方式)
- 是否可呼叫:callable(x)
- 函式/方法判斷:用 inspect,而不是看字串
- inspect.isfunction(x) → 純 Python 函式
- inspect.ismethod(x) → 綁定方法
- inspect.isbuiltin(x) → 內建(C 實作)函式/方法
- 對於類別層的成員,還可用 inspect.ismethoddescriptor(x)
實作範例:觀察 timedelta 成員
import inspect
obj = delta # 任何物件皆可
attrs = []
methods = []
for name in dir(obj):
member = getattr(obj, name)
if callable(member):
methods.append(name)
else:
attrs.append(name)
print("屬性例子:", [n for n in attrs if n in ("days","seconds","microseconds","min","max","resolution")])
print("方法例子:", [n for n in methods if n in ("total_seconds","__add__","__sub__")])
# 進一步看 total_seconds 的型態特性
m = getattr(obj, "total_seconds")
print("callable:", callable(m))
print("ismethod:", inspect.ismethod(m))
print("isfunction:", inspect.isfunction(m))
print("isbuiltin:", inspect.isbuiltin(m))
輸出結果:

不要這樣做
- “function” in str(x) 或 “method” in str(x)
- 這是人類可讀的顯示字串,可能隨版本/實作改變,結果不可靠。
- 小結
- 解析字串 → 得到 datetime
- 相減 → 得到 timedelta
- 屬性派:用 days/seconds/microseconds 組合單位
- 方法派:用 total_seconds() 快速換算
- 分辨成員型態請用 callable/inspect,而非比對字串
推薦hahow線上學習python: https://igrape.net/30afN
近期留言