首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python 判斷物件是否為字串類型:isinstance、鴨子類型、UserString 與 EAFP 風格完整解析

     編輯:更多程式設計知識

Python 中「是否為字串」看似簡單,卻藏著 str/bytes/unicode (Py2)、UserString、自訂類別等陷阱。本文對比三種判斷策略,推薦現代最佳實踐。

方法一:型別檢查(標準做法)


# Python 3:str 唯一字串型別
def is_str(obj):
    return isinstance(obj, str)

# Python 2:basestring 涵蓋 str/unicode
def is_str_py2(obj):
    return isinstance(obj, basestring)
  • 優點:快速、語意明確、支援繼承關係
  • 缺點:無法識別 UserString 或自訂字串類別

方法二:鴨子類型 / EAFP(Python 風格)


def is_string_like(obj):
    try:
        obj.lower() + obj + ' '  # 嘗試字串操作
    except Exception:
        return False
    else:
        return True
  • 優點:識別所有「表現像字串」的物件,包含 UserString、pathlib.Path、自訂類別
  • 缺點:較慢、誤判風險(任何有 lower+__add__ 的物件皆通過)

驗證 UserString 行為


from collections import UserString

s = UserString('abc')
print(isinstance(s, str))        # False (Py3)
print(is_string_like(s))         # True

# 實際應用:pathlib.Path 也通過鴨子檢查
from pathlib import Path
print(is_string_like(Path('/tmp')))  # True (支援 __str__、lower 等)

方法三:抽象基底類別 (ABC) - 現代妥協方案


from collections.abc import Sequence

def is_str_abc(obj):
    return isinstance(obj, str) or (isinstance(obj, Sequence) and hasattr(obj, 'lower'))

Python 2/3 關鍵差異表

型別Python 2Python 3
位元組字串strbytes
Unicode 字串unicodestr
共同基類basestring無 (直接用 str)
UserString 位置UserString.UserStringcollections.UserString

最佳實踐建議

  1. 內部 API / 型別提示:直接用 isinstance(obj, str) (Py3) 或 isinstance(obj, basestring) (Py2)。配合 typing.Union[str, bytes] 註解。
  2. 外部輸入驗證 / 通用工具函數:採用鴨子類型 is_string_like,或更精確的 hasattr(obj, '__str__') + 試轉換。
  3. 路徑處理:直接用 os.fspath(obj) (Py3.6+) 自動轉換 Path/字串/bytes。
  4. 避免:type(obj) == str(不支援繼承)、obj.__class__.__name__ == 'str'(脆弱)。

EAFP 哲學小結


# LBYL (Look Before You Leap) - 非 Python 風格
if hasattr(obj, 'lower'):
    result = obj.lower()

# EAFP (Easier to Ask Forgiveness than Permission) - Python 風格
try:
    result = obj.lower()
except AttributeError:
    handle_non_string(obj)

「嘗試轉換,失敗再處理」比「先檢查型別」更符合 Python 動態本質,也能自然支援未來擴充的類字串物件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved