攝影或3C

Python: 從兩個時間字串開始:用 timedelta 計算時間差,並學會分辨屬性與方法兩種做法; from datetime import datetime

目標

  • 以兩個 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']
"""
  1. 屬性派:用屬性讀數值
    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 的內部以天、秒、微秒三部分表達;自行組合就能得出任意單位。
  • 優點:不依賴額外方法,邏輯透明。
  • 缺點:容易手誤,重複性高。
  1. 方法派:用方法拿總秒數
    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

說明

  • 優點:簡潔、可讀性高。
  • 缺點:依賴該方法存在;若是自訂類型需自行實作。
  1. 兩派結果一致性檢查
assert abs(seconds_via_attrs - seconds_via_method) < 1e-9
assert abs(minutes_via_attrs - minutes_via_method) < 1e-9
print("屬性派與方法派的結果一致。")
  1. 如何分辨屬性與方法(正確方式)
  • 是否可呼叫: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)
    • 這是人類可讀的顯示字串,可能隨版本/實作改變,結果不可靠。
  1. 小結
  • 解析字串 → 得到 datetime
  • 相減 → 得到 timedelta
  • 屬性派:用 days/seconds/microseconds 組合單位
  • 方法派:用 total_seconds() 快速換算
  • 分辨成員型態請用 callable/inspect,而非比對字串

推薦hahow線上學習python: https://igrape.net/30afN

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡