中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python函數如何自定義

發布時間:2022-11-08 10:44:45 來源:億速云 閱讀:135 作者:iii 欄目:編程語言

這篇文章主要介紹“Python函數如何自定義”,在日常操作中,相信很多人在Python函數如何自定義問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python函數如何自定義”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

函數

函數是一個非常重要的概念,它們存在于所有編程語言中。函數允許我們定義一個動作(代碼塊),然后執行該動作任意次數,而無需遵循DRY原則重復自己。到目前為止,我一直在使用Python提供的一些內置函數,例如printinputlen等。

什么是函數?函數(function)是用于完成特定任務的程序代碼的自包含單元。在面向對象編程的類中,函數通常被稱作方法。不同的函數在程序中扮演著不同的角色,起著不同的作用,執行不同的動作。比如print()函數可以將對象打印到屏幕上;還有一些函數能夠返回一個值以供程序使用,比如len()將可計算長度的對象的元素個數返回給程序。

那么,為什么要使用函數呢?

第一、函數的使用可以重用代碼,省去重復性代碼的編寫,提高代碼的重復利用率。如果程序中需要多次使用某種特定的功能,那么只需要編寫一個合適的函數就可以了。程序可以在任何需要的地方調用該函數,并且同一個函數可以在不同的程序中調用,就像我們經常使用的print()和input()函數一樣。

第二、函數能封裝內部實現,保護內部數據,實現對用戶的透明。很多時候,我們把函數看做“黑盒子”,即對應一定的輸入會產生特定的結果或返回某個對象。往往函數的使用者并不是函數的編寫者,函數的使用者對黑盒子的內部行為并不需要考慮,可以把精力投入到自身業務邏輯的設計而不是函數的實現細節。只有函數的設計者或者說編寫者,才需要考慮函數內部實現的細節,如何暴露對外的接口,返回什么樣的數據,也就是API的設計。

第三、即使某種功能在程序中只使用一次,將其以函數的形式實現也是有必要的,因為函數使得程序模塊化,從“一團散沙”變成“整齊方隊”,從而有利于程序的閱讀、調用、修改和完善。例如,假設你正在編寫一個實現下面功能的程序:

  • 讀入一行數字

  • 對數字進行排序

  • 找到它們的平均值

  • 打印出一個柱狀圖

是時候創建一個函數了。

def blow_fire(): # 函數定義
  print('fire ???? ???? ????')

blow_fire() # 函數調用
blow_fire() # 可以調用多次

參數

上面的函數看起來不錯吧,但它也有一些限制。它只能執行相同的操作。讓我們使它更具可擴展性,并通過向其傳遞一些數據來使其隨意執行操作。

在定義函數時,當我們向其提供一些數據以基于該數據執行某些操作時,提供的數據稱為參數。可以為函數提供任意數量的參數。

絕大多數函數接收一定數量的參數,然后根據實際調用時提供的參數的值的不同,輸出不同的結果。前面我們說過,將函數內部的參數名字,定義得和外部變量的名字一樣是一種不好的習慣,它容易混淆思維,甚至發生錯誤。通常我們定義和給函數傳遞參數是這樣的:

x, y, z = 1, 2, 3

def add(a, b, c):

    return a+b+c

add(x, y, x)        # 使用變量,傳遞參數
add(4, 5, 6)        # 直接傳遞值也是可以的。

在上面的例子中,a,b,c叫做形式參數,簡稱形參。而x,y,z和4,5,6叫做實際參數,簡稱實參,也就是實際要傳遞的值。而我們通常討論的參數,指的都是形參。

定義函數時,參數的名字和位置確定下來,函數的接口就固定了。對于函數的調用者來說,只需要知道如何傳遞正確的參數,以及函數將返回什么樣的值就夠了,函數內部的復雜邏輯被封裝起來,調用者無需了解。Python函數的參數定義靈活度非常大。除了正常定義的位置參數外,還可以使用默認參數、動態參數和關鍵字參數,這些都是形參的種類。

位置參數

也叫必傳參數,順序參數,是最重要的,也是必須在調用函數時明確提供的參數!位置參數必須按先后順序,一一對應,個數不多不少的傳遞!

上面例子中的a,b,c就是位置參數,我們在使用add(4, 5, 6)調用時,就是將4傳給a,5傳給b,6傳給c的一一對應傳遞。類似add(4, 5, 6, 7)add(4)add(5, 4, 6)這種“畫蛇添足”、“缺胳膊少腿”和“嫁錯郎”類型的調用都是錯誤的。其中,add(5, 4, 6)的調用在語法上沒問題,但是輸出結果可能和預期的不一致。

注意: Python在做函數參數傳遞的時候不會對數據類型進行檢查,理論上你傳什么類型都可以!

def add(a, b, c):
    return a+b+c

result = add("haha", 2,  3)

但是,上面的add函數,如果你傳遞了一個字符串和兩個數字,結果是彈出異常,因為字符串無法和數字相加。這就是Python的弱數據類型和動態語言的特點。在簡單、方便的時候,需要你自己去實現數據類型檢查。

Traceback (most recent call last):
  File "F:/Python/pycharm/201705/func.py", line 33, in <module>
    result = add("haha", 2,  3)
  File "F:/Python/pycharm/201705/func.py", line 31, in add
    return a+b+c
TypeError: must be str, not int

默認參數

在函數定義時,如果給某個參數提供一個默認值,這個參數就變成了默認參數,不再是位置參數了。在調用函數的時候,我們可以給默認參數傳遞一個自定義的值,也可以使用默認值。

def power(x, n = 2):
    return x**n

ret1 = power(10)   # 使用默認的參數值n=2
ret2 = power(10, 4)  # 將4傳給n,實際計算10**4的值

上面例子中的n就是個默認參數。默認參數可以簡化函數的調用,在為最常用的情況提供簡便調用的同時,還可以在特殊情況時傳遞新的值。但是在設置默認參數時,有幾點要注意:

  • 默認參數必須在位置參數后面!

如果你違反了這點,在語法層面直接是通不過的。

# 這是一個錯誤的例子
def power(n = 2,x):
    return x**n
  • 當有多個默認參數的時候,通常將更常用的放在前面,變化較少的放后面。

def student(name, sex, age, classroom="101", tel="88880000", address="..."):
    pass
  • 在調用函數的時候,盡量給實際參數提供默認參數名。

def student(name, sex, age, classroom="101", tel="88880000", address="..."):
    pass

student('jack','male',17)       # 其它全部使用默認值
student('tom','male',18,'102','666666','beijing')    # 全部指定默認參數的值
student('mary','female',18,'102',tel='666666')  # 挑著來
student('mary','female',18,tel='666666','beijing')   #  這是錯誤的參數傳遞方式
student("mary","female",18,tel="666666",address="beijing")

注意最后兩種調用方式,倒數第二種是錯誤的,而最后一種是正確的。為什么會這樣?因為一切沒有提供參數名的實際參數,都會當做位置參數按順序從參數列表的左邊開頭往右匹配!

  • 使用參數名傳遞參數

通常我們在調用函數時,位置參數都是按順序先后傳入,而且必須在默認參數前面。但如果在位置參數傳遞時,給實參指定位置參數的參數名,那么位置參數也可以不按順序調用,例如:

def student(name, age, classroom, tel, address="..."):
    pass

student(classroom=101, name="Jack", tel=66666666, age=20)

注意指定的參數名必須和位置參數的名字一樣。

  • 默認參數盡量指向不變的對象!

使用不可變的數據類型作為默認值!

def func(a=None):
    # 注意下面的if語句
    if a is None:
        a = []
    a.append("A")
    return a

print(func())
print(func())
print(func())

將默認參數a設置為一個類似None,數字或字符串之類的不可變對象。在函數內部,將它轉換為可變的類型,比如空列表。這樣一來,不管調用多少次,運行結果都是['A']了。

動態參數

顧名思義,動態參數就是傳入的參數的個數是動態的,可以是1個、2個到任意個,還可以是0個。在不需要的時候,你完全可以忽略動態函數,不用給它傳遞任何值。

Python的動態參數有兩種,分別是*args**kwargs,這里面的關鍵是一個和兩個星號的區別,而不是argskwargs在名字上的區別,實際上你可以使用*any**whatever的方式。但就如self一樣,默認大家都使用*args**kwargs

注意:動態參數,必須放在所有的位置參數和默認參數后面!

def func(name, age, sex='male', *args, **kwargs):
    pass
*args

一個星號表示接收任意個參數。調用時,會將實際參數打包成一個元組傳入形式參數。如果參數是個列表,會將整個列表當做一個參數傳入。例如:

def func(*args):
    for arg in args:
        print(arg)

func('a', 'b', 'c')

li = [1, 2, 3]
func(li)

運行結果是:

a
b
c
[1, 2, 3]

通過循環args,我們可以獲得傳遞的每個參數。但是li這個列表,我們本意是讓它內部的1,2,3分別當做參數傳遞進去,但實際情況是列表本身被當做一個整體給傳遞進去了。怎么辦呢?使用一個星號!調用函數,傳遞實參時,在列表前面添加一個星號就可以達到目的了。實際情況是,不光列表,任何序列類型數據對象,比如字符串、元組都可以通過這種方式將內部元素逐一作為參數,傳遞給函數。而字典,則會將所有的key逐一傳遞進去。

def func(*args):
    for arg in args:
        print(arg)

li = [1, 2, 3]
func(*li)
**kwargs

兩個星表示接受鍵值對的動態參數,數量任意。調用的時候會將實際參數打包成字典。例如:

def func(**kwargs):
    for kwg in kwargs:
        print(kwg, kwargs[kwg])
        print(type(kwg))

func(k1='v1', k2=[0, 1, 2])

運行結果是:

k1 v1
<class 'str'>
k2 [0, 1, 2]
<class 'str'>

而如果我們這樣傳遞一個字典dic呢?我們希望字典內的鍵值對能夠像上面一樣被逐一傳入。

def func(**kwargs):
    for kwg in kwargs:
        print(kwg, kwargs[kwg])

dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(dic)

實際結果卻是彈出錯誤,為什么?

Traceback (most recent call last):
  File "F:/Python/pycharm/201705/func.py", line 10, in <module>
    func(dic)
TypeError: func() takes 0 positional arguments but 1 was given

因為這時候,我們其實是把dic當做一個位置參數傳遞給了func函數。而func函數并不接收任何位置函數。那怎么辦呢?使用兩個星號

def func(**kwargs):
    for kwg in kwargs:
        print(kwg, kwargs[kwg])

dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(**dic)

有了前面一個星號的基礎,這里我們應該很好理解了。兩個星號能將字典內部的鍵值對逐一傳入**kwargs

“萬能”參數

*args**kwargs組合起來使用,理論上能接受任何形式和任意數量的參數,在很多代碼中我們都能見到這種定義方式。需要注意的是,*args必須出現在**kwargs之前。

def func(*args, **kwargs):

    for arg in args:
        print(arg)

    for kwg in kwargs:
        print(kwg, kwargs[kwg])


lis = [1, 2, 3]
dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(*lis, **dic)

現在我們結合一下普通參數和萬能參數,看看會有什么情況發生:

def func(a, b, c=1, *args, **kwargs):
    for arg in args:
        print(arg)

    for kwg in kwargs:
        print(kwg, kwargs[kwg])


lis = ['aaa', 'bbb', 'ccc']
dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(1, 2, *lis, **dic)

打印結果是:

bbb
ccc
k1 v1
k2 v2

列表lis中的第一個元素‘aaa’怎么沒有打印出來?

我們改一下代碼,打印一下參數c的結果就知道了:

def func(a, b, c=1, *args, **kwargs):
    print('c的值是:', c)
    for arg in args:
        print(arg)

    for kwg in kwargs:
        print(kwg, kwargs[kwg])


lis = ['aaa', 'bbb', 'ccc']
dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(1, 2, *lis, **dic)

打印結果為:

c的值是: aaa
bbb
ccc
k1 v1
k2 v2

原來,lis的第一個元素被傳遞給參數c了!這就是Python的參數傳遞規則之一。

關鍵字參數

對于*args**kwargs參數,函數的調用者可以傳入任意不受限制的參數。比如:

def func(*args):
    pass

func("haha", 1, [], {})
func(1,2,3,4,5,6)

對于這樣的參數傳遞方式,雖然靈活性很大,但是風險也很大,可控性差,必須自己對參數進行過濾和判定。例如下面我只想要姓名、年齡和性別,就要自己寫代碼檢查:

def student(name, age, **kwargs):
    if 'sex' in kwargs:
        student_sex = kwargs['sex']

但是實際上,用戶任然可以隨意調用函數,比如student("jack", 18, xxx='male'),并且不會有任何錯誤發生。而我們實際期望的是類似student("jack", 18, sex='male')的調用。那么如何實現這種想法呢?

可以用關鍵字參數!關鍵字參數前面需要一個特殊分隔符*和位置參數及默認參數分隔開來,*后面的參數被視為關鍵字參數。在函數調用時,關鍵字參數必須傳入參數名,這和位置參數不同。如果沒有傳入參數名,調用將報錯。不同于默認參數,關鍵字參數必須傳遞,但是關鍵字參數也可以有缺省值,這時就可以不傳遞了,從而簡化調用。

我們把前面的函數改寫一下:

def student(name, age, *, sex):
    pass

student(name="jack", age=18, sex='male')

注意函數的定義體首行。

如果函數定義中已經有了一個*args參數,后面跟著的命名關鍵字參數就不再需要一個特殊分隔符*了。

def student(name, age=10, *args, sex, classroom, **kwargs):
    pass

student(name="jack", age=18, sex='male', classroom="202", k1="v1")

Python的函數參數種類多樣、形態多變,既可以實現簡單的調用,又可以傳入非常復雜的參數。需要我們多下功夫,多寫實際代碼,多做測試,逐步理清并熟練地使用參數。

返回

return是 Python 中的一個關鍵字,用于從函數返回值。為了使函數更有用,它需要根據表達式的計算返回一些值。如果未指定 return 語句,或者 return 語句的表達式的計算結果未計算為數據類型,則該函數將返回None 。在 JavaScript 世界中,這個None可以鏈接到void

return語句終止該函數并退出該函數。return

def multiplier(num1, num2):
  return num1 * num2

result = multiplier(2,3)
print(result) # 6

是時候使用return語句做一些很酷的事情了。

def sum(num1):
  def child(num2):
    return num1 + num2
  return child

add_10 = sum(10)
print(add_10(20)) # 30  (Closure!!!)
print(add_10(50)) # 60
print(add_10(100)) # 110

我剛剛驗證了Python中也有閉包的概念,就像在JavaScript中一樣。它在創建工廠功能方面非常有效。在上面的代碼塊中,我能夠創建一個通用函數add_10,并向其傳遞動態參數以生成不同的結果。這是多么酷啊!

下周將在學習Python中的函數式編程概念時對此進行更多探討。

方法只是在對象內部定義的函數,或者換句話說,它們由對象“擁有”。使用對象名后跟.運算符調用它們以執行或調用它們。

return可以返回什么?

  • 什么都不返回,僅僅return:return

  • 數字/字符串/任意數據類型:return 'hello'

  • 一個表達式:return 1+2

  • 一個判斷語句:return 100 > 99

  • 一個變量:return a

  • 一個函數調用:return func()

  • 甚至是返回自己!:return self

  • 多個返回值,以逗號分隔:return a, 1+2, "hello"

簡而言之,函數可以return幾乎任意Python對象。

文檔注釋

在某些特定的位置,用三引號包括起來的部分,也被當做注釋。但是,這種注釋有專門的作用,用于為__doc__提供文檔內容,這些內容可以通過現成的工具,自動收集起來,形成幫助文檔。比如,函數和類的說明文檔:

def func(a, b):
    """
    這個是函數的說明文檔。
    :param a: 加數
    :param b: 加數
    :return: 和
    """
    return a + b


class Foo:
    """
    這個類初始化了一個age變量
    """
    def __init__(self, age):
        self.age = age

需要強調的是這類注釋必須緊跟在定義體下面,不能在任意位置。

作用域

簡單來說,作用域意味著“我有權訪問哪些變量?這是解釋器在讀取代碼以查找變量范圍時提出的問題。在Python中,變量具有函數作用域,這意味著在函數內部定義的變量不能在函數外部訪問。

作用域指的是變量的有效范圍。變量并不是在哪個位置都可以訪問的,訪問權限取決于這個變量是在哪里賦值的,也就是在哪個作用域內的。

通常而言,在編程語言中,變量的作用域從代碼結構形式來看,有塊級、函數、類、模塊、包等由小到大的級別。但是在Python中,沒有塊級作用域,也就是類似if語句塊、for語句塊、with上下文管理器等等是不存在作用域概念的,他們等同于普通的語句。

num = 1
def confusing_function():
    num = 10
    return num

print(num) # 1 => Global Scope
print(confusing_function()) # 10 => Local Scope

這些是Python解釋器遵循的作用域規則:

  • 從本地開始。變量是否存在?然后獲取該值。如果沒有,請繼續

  • 變量是否在父函數本地作用域中定義?如果存在,則獲取值,否則繼續

  • 全局范圍內是否存在該變量?如果存在,則獲取值,否則繼續

  • 該變量是內置函數嗎?獲取值否則退出

通常,函數內部的變量無法被函數外部訪問,但內部可以訪問;類內部的變量無法被外部訪問,但類的內部可以。通俗來講,就是內部代碼可以訪問外部變量,而外部代碼通常無法訪問內部變量。

變量的作用域決定了程序的哪一部分可以訪問哪個特定的變量名稱。Python的作用域一共有4層,分別是:

  • L (Local) 局部作用域

  • E (Enclosing) 閉包函數外的函數中

  • G (Global) 全局作用域

  • B (Built-in) 內建作用域

x = int(2.9)  # 內建作用域,查找int函數

global_var = 0  # 全局作用域
def outer():
    out_var = 1  # 閉包函數外的函數中
    def inner():
        inner_var = 2  # 局部作用域

前面說的都是變量可以找得到的情況,那如果出現本身作用域沒有定義的變量,那該如何尋找呢?

Python以L –> E –> G –>B的規則查找變量,即:在局部找不到,便會去局部外的局部找(例如閉包),再找不到就會去全局找,最后去內建中找。如果這樣還找不到,那就提示變量不存在的錯誤。例如下面的代碼,函數func內部并沒有定義變量a,可是print函數需要打印a,那怎么辦?向外部尋找!按照L –> E –> G –>B的規則,層層查詢,這個例子很快就從外層查找到了a,并且知道它被賦值為1,于是就打印了1。

a = 1

def func():
    print(a)

全局變量和局部變量

定義在函數內部的變量擁有一個局部作用域,被叫做局部變量,定義在函數外的擁有全局作用域的變量,被稱為全局變量。(類、模塊等同理)

所謂的局部變量是相對的。局部變量也有可能是更小范圍內的變量的外部變量。

局部變量只能在其被聲明的函數內部訪問,而全局變量可以在整個程序范圍內訪問。調用函數時,所有在函數內聲明的變量名稱都將被加入到作用域中。

a = 1               # 全局變量

def func():
    b = 2           # 局部變量
    print(a)        # 可訪問全局變量a,無法訪問它內部的c

    def inner():
        c = 3       # 更局部的變量
        print(a)    # 可以訪問全局變量a
        print(b)    # b對于inner函數來說,就是外部變量
        print(c)

global和nonlocal關鍵字

我們先看下面的例子:

total = 0                        # total是一個全局變量

def plus( arg1, arg2 ):
    total = arg1 + arg2          # total在這里是局部變量.
    print("函數內局部變量total=  ", total)
    print("函數內的total的內存地址是: ", id(total))
    return total

plus(10, 20)
print("函數外部全局變量total= ", total)
print("函數外的total的內存地址是: ", id(total))

很明顯,函數plus內部通過total = arg1 + arg2語句,新建了一個局部變量total,它和外面的全局變量total是兩碼事。而如果我們,想要在函數內部修改外面的全局變量total呢?使用global關鍵字!

global:指定當前變量使用外部的全局變量

total = 0                        # total是一個全局變量

def plus( arg1, arg2 ):
    global total    # 使用global關鍵字申明此處的total引用外部的total
    total = arg1 + arg2          
    print("函數內局部變量total=  ", total)
    print("函數內的total的內存地址是: ", id(total))
    return total

plus(10, 20)
print("函數外部全局變量total= ", total)
print("函數外的total的內存地址是: ", id(total))

打印結果是:

函數內局部變量total=   30
函數內的total的內存地址是:  503494624
函數外部全局變量total=  30
函數外的total的內存地址是:  503494624

我們再來看下面的例子:

a = 1
print("函數outer調用之前全局變量a的內存地址: ", id(a))

def outer():
    a = 2
    print("函數outer調用之時閉包外部的變量a的內存地址: ", id(a))
    def inner():
        a = 3
        print("函數inner調用之后閉包內部變量a的內存地址: ", id(a))
    inner()
    print("函數inner調用之后,閉包外部的變量a的內存地址: ", id(a))
outer()
print("函數outer執行完畢,全局變量a的內存地址: ", id(a))

如果你將前面的知識點都理解通透了,那么這里應該沒什么問題,三個a各是各的a,各自有不同的內存地址,是三個不同的變量。打印結果也很好的證明了這點:

函數outer調用之前全局變量a的內存地址:  493204544
函數outer調用之時閉包外部的變量a的內存地址:  493204576
函數inner調用之后閉包內部變量a的內存地址:  493204608
函數inner調用之后,閉包外部的變量a的內存地址:  493204576
函數outer執行完畢,全局變量a的內存地址:  493204544

那么,如果,inner內部想使用outer里面的那個a,而不是全局變量的那個a,怎么辦?用global關鍵字?先試試看吧:

a = 1
print("函數outer調用之前全局變量a的內存地址: ", id(a))
def outer():
    a = 2
    print("函數outer調用之時閉包外部的變量a的內存地址: ", id(a))
    def inner():
        global a   # 注意這行
        a = 3
        print("函數inner調用之后閉包內部變量a的內存地址: ", id(a))
    inner()
    print("函數inner調用之后,閉包外部的變量a的內存地址: ", id(a))
outer()
print("函數outer執行完畢,全局變量a的內存地址: ", id(a))

運行結果如下,很明顯,global使用的是全局變量a。

函數outer調用之前全局變量a的內存地址:  494384192
函數outer調用之時閉包外部的變量a的內存地址:  494384224
函數inner調用之后閉包內部變量a的內存地址:  494384256
函數inner調用之后,閉包外部的變量a的內存地址:  494384224
函數outer執行完畢,全局變量a的內存地址:  494384256

那怎么辦呢?使用nonlocal關鍵字!它可以修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量。將global a改成nonlocal a,代碼這里我就不重復貼了,運行后查看結果,可以看到我們真的引用了outer函數的a變量。

函數outer調用之前全局變量a的內存地址:  497726528
函數outer調用之時閉包外部的變量a的內存地址:  497726560
函數inner調用之后閉包內部變量a的內存地址:  497726592
函數inner調用之后,閉包外部的變量a的內存地址:  497726592
函數outer執行完畢,全局變量a的內存地址:  497726528

到此,關于“Python函數如何自定義”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

镇雄县| 鹿泉市| 客服| 台湾省| 郑州市| 康马县| 平利县| 丰城市| 友谊县| 正宁县| 嘉兴市| 五家渠市| 印江| 岳阳县| 丰顺县| 扎鲁特旗| 宜宾县| 浙江省| 上蔡县| 景泰县| 福建省| 莒南县| 沙坪坝区| 张家川| 河南省| 正安县| 铜川市| 安宁市| 喜德县| 西林县| 安陆市| 翼城县| 喀喇| 天等县| 红安县| 黎川县| 双牌县| 临邑县| 康平县| 稻城县| 瑞安市|