最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文淺析Python如何構(gòu)建優(yōu)雅的異常體系

 更新時(shí)間:2026年03月04日 09:03:12   作者:銘淵老黃  
這篇文章主要介紹了Python異常處理的核心原則與最佳實(shí)踐,文內(nèi)首先指出異常處理常被低估,通過真實(shí)案例展示了不當(dāng)處理帶來的隱患,隨后解析了Python異常機(jī)制的本質(zhì)是一種控制流信號(hào),并詳細(xì)介紹了異常層級(jí)結(jié)構(gòu),有需要的小伙伴可以了解下

“程序里有兩種錯(cuò)誤:一種是你預(yù)料到的,一種是你沒預(yù)料到的。好的異常處理,就是讓這兩種錯(cuò)誤都無處遁形。”——每一位在生產(chǎn)事故復(fù)盤會(huì)上沉默過的開發(fā)者

一、引言:異常處理,被低估的編程藝術(shù)

我曾接手過一個(gè)遺留項(xiàng)目,全文搜索 except,發(fā)現(xiàn)幾乎每一處都寫著:

try:
    do_something()
except Exception:
    pass

那一刻,我感受到了一種特殊的絕望——不是因?yàn)榇a崩了,而是因?yàn)?strong>代碼永遠(yuǎn)不會(huì)崩,所有的錯(cuò)誤都被悄無聲息地吞掉了,系統(tǒng)帶著滿身隱患繼續(xù)運(yùn)行,直到某天以一種完全出乎意料的方式徹底爆發(fā)。

異常處理,是 Python 編程中最容易被"隨便寫寫"的部分,卻也是最能體現(xiàn)一個(gè)工程師成熟度的地方。本文將從哲學(xué)層面的"何時(shí)捕獲、何時(shí)傳播"講到工程層面的"如何設(shè)計(jì)自定義異常體系",用真實(shí)代碼和實(shí)戰(zhàn)案例,幫你建立一套完整的異常處理思維框架。

二、理解 Python 異常的底層邏輯

2.1 異常不是"錯(cuò)誤",它是"信號(hào)"

在 Python 中,異常(Exception)本質(zhì)上是一種控制流機(jī)制——當(dāng)程序遇到無法繼續(xù)正常執(zhí)行的情況時(shí),它拋出一個(gè)信號(hào),沿著調(diào)用棧向上傳播,直到被某處捕獲或?qū)е鲁绦蚪K止。

函數(shù) C 拋出異常
    ↑ 傳播
函數(shù) B(沒有捕獲)
    ↑ 傳播
函數(shù) A(捕獲并處理)
    ↑ 程序繼續(xù)

這個(gè)傳播機(jī)制是異常的核心價(jià)值:它把"發(fā)現(xiàn)問題的地方"和"處理問題的地方"解耦了。你不需要在每一層函數(shù)里都檢查返回值,只需要在合適的層級(jí)處理異常。

2.2 Python 異常層級(jí)一覽

BaseException
├── SystemExit          # sys.exit() 觸發(fā),不應(yīng)被普通 except 捕獲
├── KeyboardInterrupt   # Ctrl+C,同上
├── GeneratorExit       # 生成器關(guān)閉
└── Exception           # 所有"正常"異常的基類
    ├── ArithmeticError
    │   ├── ZeroDivisionError
    │   └── OverflowError
    ├── LookupError
    │   ├── IndexError
    │   └── KeyError
    ├── ValueError
    ├── TypeError
    ├── IOError / OSError
    ├── RuntimeError
    └── ... (還有數(shù)十種內(nèi)置異常)

一個(gè)關(guān)鍵認(rèn)知:永遠(yuǎn)不要用 except BaseException 或裸 except:,除非你明確知道自己在做什么——它會(huì)連 KeyboardInterruptSystemExit 也一并吞掉,導(dǎo)致程序無法被正常終止。

三、核心哲學(xué):何時(shí)捕獲,何時(shí)傳播

這是異常處理中最難回答、也最值得深思的問題。我的答案是一個(gè)判斷框架,分四個(gè)維度來思考:

3.1 你能"修復(fù)"這個(gè)異常嗎

能修復(fù) → 捕獲并處理

# 場(chǎng)景:讀取配置文件,文件不存在時(shí)使用默認(rèn)配置
def load_config(path: str) -> dict:
    try:
        with open(path, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        # 我們能處理這種情況:使用默認(rèn)值
        logger.warning(f"配置文件 {path} 不存在,使用默認(rèn)配置")
        return DEFAULT_CONFIG
    except json.JSONDecodeError as e:
        # 配置文件格式錯(cuò)誤,這是調(diào)用者的問題,重新拋出更有意義的異常
        raise ConfigurationError(f"配置文件格式錯(cuò)誤: {e}") from e

不能修復(fù) → 讓它傳播(或轉(zhuǎn)換后傳播)

# 場(chǎng)景:數(shù)據(jù)庫(kù)寫入失敗
def save_user(user: User) -> None:
    try:
        db.execute("INSERT INTO users ...", user.to_dict())
    except DatabaseConnectionError:
        # 我無法修復(fù)數(shù)據(jù)庫(kù)連接問題,讓它向上傳播
        # 但可以加上上下文信息
        logger.error(f"保存用戶 {user.id} 失敗")
        raise  # 重新拋出原始異常,保留完整堆棧

3.2 "吞異常"是萬惡之源

# ? 極其危險(xiǎn)的寫法:異常被吞掉,程序悄悄出錯(cuò)
def get_user_age(user_id: int) -> int:
    try:
        user = db.get_user(user_id)
        return user.age
    except Exception:
        pass  # 發(fā)生了什么?沒人知道。

# ? 至少要記錄日志,讓問題有跡可查
def get_user_age(user_id: int) -> int | None:
    try:
        user = db.get_user(user_id)
        return user.age
    except UserNotFoundError:
        logger.warning(f"用戶 {user_id} 不存在")
        return None
    except Exception:
        logger.exception(f"獲取用戶 {user_id} 年齡時(shí)發(fā)生未預(yù)期錯(cuò)誤")
        raise  # 未知錯(cuò)誤,必須傳播

3.3 捕獲異常的"精確度原則"

異常捕獲的范圍應(yīng)該盡可能精確,就像外科手術(shù)一樣——切掉該切的,保留該保留的。

# ? 過于寬泛:一網(wǎng)打盡,隱患無窮
try:
    result = complex_calculation(data)
    save_to_database(result)
    send_notification(result)
except Exception as e:
    logger.error(f"出錯(cuò)了: {e}")

# ? 精確捕獲:每種異常獨(dú)立處理
try:
    result = complex_calculation(data)
except (ValueError, TypeError) as e:
    raise InvalidInputError(f"輸入數(shù)據(jù)格式錯(cuò)誤: {e}") from e

try:
    save_to_database(result)
except DatabaseError as e:
    logger.error(f"數(shù)據(jù)庫(kù)保存失敗,結(jié)果已緩存")
    cache.store(result)  # 降級(jí)處理
    raise

try:
    send_notification(result)
except NotificationError:
    # 通知失敗不影響主流程,記錄即可
    logger.warning("通知發(fā)送失敗,將在下次重試")

3.4 "異常邊界"思維

一個(gè)成熟的系統(tǒng)應(yīng)該有明確的異常邊界:在邊界內(nèi)部,異??梢宰杂蓚鞑?;在邊界處,對(duì)異常進(jìn)行統(tǒng)一處理(轉(zhuǎn)換、記錄、降級(jí))。

常見的異常邊界層級(jí):

  • Web 框架層:將所有未處理異常轉(zhuǎn)換為 HTTP 錯(cuò)誤響應(yīng)
  • Service 層:將底層技術(shù)異常(DB、網(wǎng)絡(luò))轉(zhuǎn)換為業(yè)務(wù)異常
  • Task/Job 層:捕獲所有異常,記錄日志,決定重試或放棄

四、設(shè)計(jì)自定義異常體系

4.1 為什么需要自定義異常

內(nèi)置異常(如 ValueErrorRuntimeError)是通用的,它們?nèi)狈I(yè)務(wù)語義。當(dāng)你的系統(tǒng)拋出 ValueError: invalid user id 時(shí),調(diào)用者很難判斷該如何應(yīng)對(duì);但如果拋出 UserNotFoundError,意圖立刻清晰。

自定義異常的三大價(jià)值:

  • 語義明確:異常名本身就是文檔
  • 精確捕獲:調(diào)用者可以只捕獲自己關(guān)心的異常類型
  • 攜帶上下文:可以附加豐富的錯(cuò)誤信息和診斷數(shù)據(jù)

4.2 構(gòu)建分層異常體系

以一個(gè)電商系統(tǒng)為例,設(shè)計(jì)如下異常層級(jí):

# exceptions.py —— 電商系統(tǒng)異常體系

class AppError(Exception):
    """
    應(yīng)用級(jí)基礎(chǔ)異常,所有自定義異常的根
    攜帶錯(cuò)誤碼,便于 API 響應(yīng)和監(jiān)控告警
    """
    def __init__(self, message: str, code: str = "APP_ERROR", details: dict = None):
        super().__init__(message)
        self.message = message
        self.code = code
        self.details = details or {}

    def to_dict(self) -> dict:
        """轉(zhuǎn)換為 API 響應(yīng)格式"""
        return {
            "error": self.code,
            "message": self.message,
            "details": self.details
        }

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(code={self.code!r}, message={self.message!r})"


# ─── 領(lǐng)域?qū)樱喊礃I(yè)務(wù)模塊劃分 ────────────────────────

class UserError(AppError):
    """用戶模塊異?;?""
    pass

class UserNotFoundError(UserError):
    """用戶不存在"""
    def __init__(self, user_id: int | str):
        super().__init__(
            message=f"用戶 {user_id} 不存在",
            code="USER_NOT_FOUND",
            details={"user_id": user_id}
        )
        self.user_id = user_id

class UserPermissionError(UserError):
    """用戶權(quán)限不足"""
    def __init__(self, user_id: int, required_permission: str):
        super().__init__(
            message=f"用戶 {user_id} 缺少權(quán)限: {required_permission}",
            code="PERMISSION_DENIED",
            details={"user_id": user_id, "required": required_permission}
        )


class OrderError(AppError):
    """訂單模塊異?;?""
    pass

class OrderNotFoundError(OrderError):
    def __init__(self, order_id: str):
        super().__init__(
            message=f"訂單 {order_id} 不存在",
            code="ORDER_NOT_FOUND",
            details={"order_id": order_id}
        )

class InsufficientStockError(OrderError):
    """庫(kù)存不足"""
    def __init__(self, product_id: str, requested: int, available: int):
        super().__init__(
            message=f"商品 {product_id} 庫(kù)存不足(需要 {requested},剩余 {available})",
            code="INSUFFICIENT_STOCK",
            details={
                "product_id": product_id,
                "requested": requested,
                "available": available
            }
        )

class OrderStateError(OrderError):
    """訂單狀態(tài)流轉(zhuǎn)錯(cuò)誤"""
    def __init__(self, order_id: str, current_state: str, expected_state: str):
        super().__init__(
            message=f"訂單 {order_id} 當(dāng)前狀態(tài)為 {current_state},無法執(zhí)行此操作(需要 {expected_state})",
            code="INVALID_ORDER_STATE",
            details={
                "order_id": order_id,
                "current_state": current_state,
                "expected_state": expected_state
            }
        )


# ─── 基礎(chǔ)設(shè)施層:技術(shù)異常 ────────────────────────

class InfrastructureError(AppError):
    """基礎(chǔ)設(shè)施層異?;?""
    pass

class DatabaseError(InfrastructureError):
    def __init__(self, operation: str, cause: Exception = None):
        super().__init__(
            message=f"數(shù)據(jù)庫(kù)操作失敗: {operation}",
            code="DATABASE_ERROR"
        )
        self.__cause__ = cause

class ExternalServiceError(InfrastructureError):
    """第三方服務(wù)調(diào)用失敗"""
    def __init__(self, service_name: str, status_code: int = None):
        super().__init__(
            message=f"外部服務(wù) {service_name} 調(diào)用失敗",
            code="EXTERNAL_SERVICE_ERROR",
            details={"service": service_name, "status_code": status_code}
        )

異常層級(jí)示意圖:

AppError
├── UserError
│   ├── UserNotFoundError
│   └── UserPermissionError
├── OrderError
│   ├── OrderNotFoundError
│   ├── InsufficientStockError
│   └── OrderStateError
└── InfrastructureError
    ├── DatabaseError
    └── ExternalServiceError

4.3 在業(yè)務(wù)邏輯中使用異常體系

# order_service.py —— 異常體系的實(shí)際使用

class OrderService:

    def create_order(self, user_id: int, items: list[dict]) -> Order:
        """創(chuàng)建訂單,展示完整的異常處理鏈路"""

        # 1. 驗(yàn)證用戶
        user = self._get_user_or_raise(user_id)

        # 2. 檢查庫(kù)存(精確捕獲,各個(gè)擊破)
        for item in items:
            self._check_stock(item["product_id"], item["quantity"])

        # 3. 創(chuàng)建訂單
        try:
            order = Order.create(user_id=user_id, items=items)
            self.db.save(order)
            return order
        except Exception as e:
            # 將底層異常轉(zhuǎn)換為業(yè)務(wù)異常,附加上下文
            raise DatabaseError("創(chuàng)建訂單", cause=e) from e

    def _get_user_or_raise(self, user_id: int) -> User:
        """獲取用戶,不存在則拋出語義明確的異常"""
        user = self.db.find_user(user_id)
        if user is None:
            raise UserNotFoundError(user_id)
        return user

    def _check_stock(self, product_id: str, quantity: int) -> None:
        """檢查庫(kù)存,不足則拋出攜帶詳細(xì)信息的異常"""
        product = self.db.find_product(product_id)
        if product.stock < quantity:
            raise InsufficientStockError(
                product_id=product_id,
                requested=quantity,
                available=product.stock
            )

    def cancel_order(self, order_id: str, user_id: int) -> None:
        """取消訂單,演示狀態(tài)校驗(yàn)異常"""
        order = self.db.find_order(order_id)
        if order is None:
            raise OrderNotFoundError(order_id)

        if order.status != "pending":
            raise OrderStateError(
                order_id=order_id,
                current_state=order.status,
                expected_state="pending"
            )

        order.cancel()
        self.db.save(order)

4.4 在 API 層統(tǒng)一處理異常

# api/exception_handlers.py —— FastAPI 統(tǒng)一異常處理

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.exception_handler(AppError)
async def app_error_handler(request: Request, exc: AppError) -> JSONResponse:
    """
    統(tǒng)一處理所有業(yè)務(wù)異常,轉(zhuǎn)換為標(biāo)準(zhǔn) HTTP 響應(yīng)
    """
    # 根據(jù)異常類型決定 HTTP 狀態(tài)碼
    status_code_map = {
        "USER_NOT_FOUND": 404,
        "ORDER_NOT_FOUND": 404,
        "PERMISSION_DENIED": 403,
        "INSUFFICIENT_STOCK": 409,
        "INVALID_ORDER_STATE": 422,
        "DATABASE_ERROR": 503,
        "EXTERNAL_SERVICE_ERROR": 502,
    }
    status_code = status_code_map.get(exc.code, 500)

    # 服務(wù)端錯(cuò)誤記錄詳細(xì)日志
    if status_code >= 500:
        logger.error(f"服務(wù)端錯(cuò)誤: {exc!r}", exc_info=True)
    else:
        logger.info(f"業(yè)務(wù)異常: {exc!r}")

    return JSONResponse(
        status_code=status_code,
        content=exc.to_dict()
    )

@app.exception_handler(Exception)
async def unhandled_error_handler(request: Request, exc: Exception) -> JSONResponse:
    """兜底處理:未被捕獲的異常"""
    logger.critical(f"未處理的異常: {exc!r}", exc_info=True)
    return JSONResponse(
        status_code=500,
        content={"error": "INTERNAL_ERROR", "message": "服務(wù)器內(nèi)部錯(cuò)誤"}
    )

五、進(jìn)階技巧:讓異常處理更優(yōu)雅

5.1 使用raise ... from ...保留異常鏈

# ? 異常鏈:保留原始原因,同時(shí)提供業(yè)務(wù)上下文
try:
    raw_data = json.loads(request_body)
except json.JSONDecodeError as e:
    raise InvalidRequestError("請(qǐng)求體不是合法的 JSON 格式") from e
    # 上面這行讓異常信息變?yōu)椋?
    # InvalidRequestError: 請(qǐng)求體不是合法的 JSON 格式
    # The above exception was the direct cause of the following exception:
    # json.JSONDecodeError: ...(原始錯(cuò)誤保留)

# ? 丟失原始異常信息(調(diào)試時(shí)抓瞎)
try:
    raw_data = json.loads(request_body)
except json.JSONDecodeError:
    raise InvalidRequestError("請(qǐng)求體不是合法的 JSON 格式")

5.2 上下文管理器實(shí)現(xiàn)資源安全

# 自定義上下文管理器:事務(wù)管理
from contextlib import contextmanager

@contextmanager
def db_transaction(db_session):
    """
    確保數(shù)據(jù)庫(kù)事務(wù)在異常時(shí)自動(dòng)回滾
    """
    try:
        yield db_session
        db_session.commit()
        logger.debug("事務(wù)提交成功")
    except AppError:
        db_session.rollback()
        logger.warning("業(yè)務(wù)異常,事務(wù)已回滾")
        raise  # 業(yè)務(wù)異常繼續(xù)傳播
    except Exception as e:
        db_session.rollback()
        logger.error("未知異常,事務(wù)已回滾", exc_info=True)
        raise DatabaseError("事務(wù)執(zhí)行失敗") from e
    finally:
        db_session.close()

# 使用
with db_transaction(session) as txn:
    txn.execute("UPDATE ...")
    txn.execute("INSERT ...")
    # 任何異常都會(huì)觸發(fā)回滾

5.3 重試機(jī)制:優(yōu)雅處理瞬時(shí)故障

import time
import functools
from typing import Type

def retry(
    exceptions: tuple[Type[Exception], ...],
    max_attempts: int = 3,
    delay: float = 1.0,
    backoff: float = 2.0
):
    """
    裝飾器:對(duì)指定異常類型進(jìn)行自動(dòng)重試(指數(shù)退避)
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            attempt = 0
            current_delay = delay

            while attempt < max_attempts:
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    attempt += 1
                    if attempt >= max_attempts:
                        logger.error(f"{func.__name__} 重試 {max_attempts} 次后仍失敗: {e}")
                        raise

                    logger.warning(
                        f"{func.__name__} 第 {attempt} 次失敗: {e},"
                        f"{current_delay:.1f}s 后重試"
                    )
                    time.sleep(current_delay)
                    current_delay *= backoff

        return wrapper
    return decorator


# 使用:對(duì)網(wǎng)絡(luò)請(qǐng)求、外部服務(wù)調(diào)用啟用重試
@retry(exceptions=(ExternalServiceError, ConnectionError), max_attempts=3, delay=0.5)
def call_payment_api(order_id: str, amount: float) -> dict:
    response = requests.post(PAYMENT_API_URL, json={"order_id": order_id, "amount": amount})
    if response.status_code != 200:
        raise ExternalServiceError("payment-api", response.status_code)
    return response.json()

5.4 避免異常處理的常見反模式

# 反模式一:用異??刂普A鞒蹋ㄐ阅懿?,語義混亂)
# ?
def find_user(user_id):
    try:
        return User.objects.get(id=user_id)
    except User.DoesNotExist:
        return None  # 這種情況應(yīng)該用 .filter().first()

# ?
def find_user(user_id):
    return User.objects.filter(id=user_id).first()


# 反模式二:過于細(xì)碎的 try/except 塊
# ?
try:
    a = int(input_a)
except ValueError:
    a = 0
try:
    b = int(input_b)
except ValueError:
    b = 0

# ? 提取成函數(shù)
def safe_int(value: str, default: int = 0) -> int:
    try:
        return int(value)
    except (ValueError, TypeError):
        return default

a = safe_int(input_a)
b = safe_int(input_b)


# 反模式三:在 finally 中使用 return(會(huì)吞掉異常?。?
# ?
def dangerous():
    try:
        raise ValueError("出錯(cuò)了")
    finally:
        return 42  # 異常被吞掉,函數(shù)返回 42

# ? finally 只做清理,不做返回
def safe():
    try:
        raise ValueError("出錯(cuò)了")
    finally:
        cleanup()  # 只清理資源

六、最佳實(shí)踐總結(jié)

經(jīng)過多年項(xiàng)目實(shí)戰(zhàn),我總結(jié)了異常處理的"七條準(zhǔn)則":

  • 只捕獲你能處理的異常,其余的讓它傳播
  • 捕獲越精確越好,except Exception 是最后手段
  • 永遠(yuǎn)不要裸 except:except BaseException
  • 吞掉異常必須有充分理由,并記錄日志
  • raise from 保留異常鏈,別讓堆棧信息丟失
  • 自定義異常要攜帶足夠的上下文信息
  • 在系統(tǒng)邊界(API層、任務(wù)層)統(tǒng)一處理未捕獲異常

七、前沿視角:異常處理的演進(jìn)

隨著 Python 生態(tài)的演進(jìn),異常處理也在悄然升級(jí):

Python 3.11 的 ExceptionGroup:允許同時(shí)拋出多個(gè)異常,配合 except* 語法,專為 asyncio 并發(fā)場(chǎng)景設(shè)計(jì):

# Python 3.11+:并發(fā)任務(wù)的多異常處理
async def fetch_all(urls):
    async with asyncio.TaskGroup() as tg:
        tasks = [tg.create_task(fetch(url)) for url in urls]

# 使用 except* 捕獲特定類型的并發(fā)異常
try:
    await fetch_all(urls)
except* TimeoutError as eg:
    print(f"超時(shí)的任務(wù)數(shù): {len(eg.exceptions)}")
except* ConnectionError as eg:
    print(f"連接失敗的任務(wù)數(shù): {len(eg.exceptions)}")

Result 類型模式(函數(shù)式風(fēng)格,來自 Rust 的啟發(fā)):

from dataclasses import dataclass
from typing import Generic, TypeVar

T = TypeVar("T")
E = TypeVar("E", bound=Exception)

@dataclass
class Ok(Generic[T]):
    value: T

@dataclass
class Err(Generic[E]):
    error: E

Result = Ok[T] | Err[E]

def safe_divide(a: float, b: float) -> Result:
    if b == 0:
        return Err(ZeroDivisionError("除數(shù)不能為零"))
    return Ok(a / b)

# 調(diào)用者顯式處理兩種情況
match safe_divide(10, 0):
    case Ok(value=v):
        print(f"結(jié)果: {v}")
    case Err(error=e):
        print(f"計(jì)算失敗: {e}")

八、總結(jié)與互動(dòng)

回顧本文的核心思路:

  • 哲學(xué)層面:異常是信號(hào),不是敵人;捕獲是承諾,不是逃避
  • 判斷框架:能修復(fù)就捕獲,不能修復(fù)就傳播,永遠(yuǎn)不要吞掉
  • 工程層面:分層異常體系讓代碼語義清晰,API 邊界統(tǒng)一兜底
  • 進(jìn)階技巧:異常鏈、重試裝飾器、上下文管理器讓處理更優(yōu)雅

異常處理的最高境界,是讓閱讀代碼的人一眼就知道:這里可能出什么問題,出了問題會(huì)怎樣處理。 這不僅僅是技術(shù)的體現(xiàn),更是對(duì)團(tuán)隊(duì)協(xié)作和系統(tǒng)可維護(hù)性的深刻尊重。

到此這篇關(guān)于一文淺析Python如何構(gòu)建優(yōu)雅的異常體系的文章就介紹到這了,更多相關(guān)Python異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

宁化县| 盐边县| 左贡县| 布拖县| 安庆市| 隆昌县| 苍山县| 东乌| 门源| 罗田县| 崇礼县| 兴安盟| 通许县| 赤水市| 中西区| 大港区| 金山区| 建德市| 玉屏| 包头市| 醴陵市| 洱源县| 白水县| 宜川县| 海林市| 桐乡市| 东乡县| 扶风县| 渝北区| 天津市| 吉安市| 达日县| 眉山市| 海原县| 卢湾区| 仲巴县| 福州市| 沅江市| 宁晋县| 揭东县| 历史|