天天看點

第五章 Python函數你知多少

函數作用:把一些複雜的代碼封裝起來,函數一般都是一個功能,用的時候才調用,提高重複使用率和簡化程式結構。

5.1 文法

1

2

3

<code>def</code> <code>functionName(parms1, parms2, ...):</code>

<code>   </code><code>code block</code>

<code>   </code><code>return</code> <code>expression</code>

函數以def關鍵字開頭,空格後跟函數名,括号裡面是參數,用于傳參,函數代碼段裡面引用。

5.2 函數定義與調用

4

5

6

7

8

9

<code># 定義函數</code>

<code>&gt;&gt;&gt; </code><code>def</code> <code>func():</code>

<code>...   </code><code>print</code> <code>"Hello world!"</code>

<code>...   </code><code>return</code> <code>"Hello world!"</code> 

<code>...</code>

<code># 調用函數</code>

<code>&gt;&gt;&gt; func()</code>

<code>Hello world!</code>

<code>'Hello world!'</code>

當我們定義好函數,是不執行的,沒有任何輸出。當輸入函數名後跟雙小括号才會執行函數裡寫的代碼。

順便說下print和return差別:

有沒有點奇怪!為什麼print和return輸出一樣呢,return就加個單引号,貌似也沒啥明顯差別啊!其實在解釋器下所有的結果都會輸出的。

先了解下return作用:結束函數,并傳回一個值。如果不跟表達式,會傳回一個None。

好,那麼我們深入了解下他們差別,舉個例子,寫個py程式:

<code>#!/usr/bin/env python</code>

<code>def</code> <code>func():</code>

<code>    </code><code>print</code> <code>"1: Hello world!"</code>

<code>    </code><code>return</code> <code>"2: Hello world!"</code>

<code>func()</code>

<code># python test.py</code>

<code>1</code><code>: Hello world!</code>

明白點了嘛?print是列印對象的值,而return是傳回對象的值。也就是說你return預設是将對象值存儲起來,要想知道裡面的值,可以用print可以列印。

<code>print</code> <code>func()</code>

<code>2</code><code>: Hello world!</code>

為什麼函數裡面不用print就在這裡,往往我們定義一個函數是不需要列印的,而是交給其他代碼去處理這個函數傳回值。當然,print在調試函數代碼時會起到很好的幫助。

5.3 函數參數

  5.3.1 接受參數

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(a, b):    </code>

<code>    </code><code>...   </code><code>print</code> <code>a </code><code>+</code> <code>b</code>

<code>    </code><code>...</code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>, </code><code>2</code><code>)</code>

<code>    </code><code>3</code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>)</code>

<code>    </code><code>Traceback (most recent call last):</code>

<code>      </code><code>File</code> <code>"&lt;stdin&gt;"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code>&lt;module&gt;</code>

<code>    </code><code>TypeError: func() takes exactly </code><code>2</code> <code>arguments (</code><code>3</code> <code>given)</code>

   a和b可以了解為是個變量,可由裡面代碼塊引用。調用函數時,小括号裡面的表達式數量要對應函數參數數量,并且按傳參按位置賦予函數參數位置。如果數量不對應,會抛出TypeError錯誤。

   當然,函數參數也可以是數組:

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(a):    </code>

<code>    </code><code>...   </code><code>print</code> <code>a</code>

<code>    </code><code>&gt;&gt;&gt; func([</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>])</code>

<code>    </code><code>[</code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>]</code>

<code>    </code><code>&gt;&gt;&gt; func({</code><code>'a'</code><code>:</code><code>1</code><code>,</code><code>'b'</code><code>:</code><code>2</code><code>})</code>

<code>    </code><code>{</code><code>'a'</code><code>: </code><code>1</code><code>, </code><code>'b'</code><code>: </code><code>2</code><code>}</code>

   如果不想一一對應傳參,可以指定參數值:

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(a,b):    </code>

<code>    </code><code>&gt;&gt;&gt; func(b</code><code>=</code><code>2</code><code>,a</code><code>=</code><code>1</code><code>)</code>

   5.3.2 函數參數預設值

   參數預設值是預先定義好,如果調用函數時傳入了這個值,那麼将以傳入的為實際值,否則是預設值。

<code>    </code><code>&gt;&gt;&gt; def func(a, b=2):    </code>

<code>    </code><code>...   print a + b</code>

<code>    </code><code>&gt;&gt;&gt; func(1)</code>

<code>    </code><code>&gt;&gt;&gt; func(1, 3)</code>

<code>    </code><code>4</code>

   5.3.3 接受任意數量參數

   上面方式固定了參數多個,當不知道多少參數時候可以用以下方式。

   單個星号使用:

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(</code><code>*</code><code>a):         </code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>)</code>

<code>    </code><code>(</code><code>1</code><code>, </code><code>2</code><code>, </code><code>3</code><code>)</code>

   單個星号存儲為一個元組。

   兩個星号使用:

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(</code><code>*</code><code>*</code><code>a):    </code>

<code>    </code><code>&gt;&gt;&gt; func(a</code><code>=</code><code>1</code><code>, b</code><code>=</code><code>2</code><code>, c</code><code>=</code><code>3</code><code>)</code>

<code>    </code><code>{</code><code>'a'</code><code>: </code><code>1</code><code>, </code><code>'c'</code><code>: </code><code>3</code><code>, </code><code>'b'</code><code>: </code><code>2</code><code>}</code>

   兩個星号存儲為一個字典。可見它們都是以數組的形式傳入。

   你也許在查資料的時候,會看到這樣寫的函數參數(*args, **kwargs),與上面隻是名字不一樣罷了 :

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs):    </code>

<code>    </code><code>...   </code><code>print</code> <code>args</code>

<code>    </code><code>...   </code><code>print</code> <code>kwargs</code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>,a</code><code>=</code><code>1</code><code>,b</code><code>=</code><code>2</code><code>,c</code><code>=</code><code>3</code><code>)</code>

   與普通參數一起使用:

10

11

12

13

14

15

16

17

18

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(a, b, </code><code>*</code><code>c):    </code>

<code>    </code><code>...   </code><code>print</code> <code>c</code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>,</code><code>5</code><code>,</code><code>6</code><code>)</code>

<code>    </code><code>(</code><code>3</code><code>, </code><code>5</code><code>, </code><code>6</code><code>)</code>

<code>    </code><code>&gt;&gt;&gt; </code><code>def</code> <code>func(a, b, </code><code>*</code><code>*</code><code>c):</code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>,</code><code>2</code><code>,a</code><code>=</code><code>1</code><code>,b</code><code>=</code><code>2</code><code>,c</code><code>=</code><code>3</code><code>)</code>

<code>    </code><code>TypeError: func() got multiple values </code><code>for</code> <code>keyword argument </code><code>'a'</code>

<code>    </code><code>&gt;&gt;&gt; func(</code><code>1</code><code>,</code><code>2</code><code>,c</code><code>=</code><code>3</code><code>,d</code><code>=</code><code>4</code><code>,e</code><code>=</code><code>5</code><code>)</code>

<code>    </code><code>{</code><code>'c'</code><code>: </code><code>3</code><code>, </code><code>'e'</code><code>: </code><code>5</code><code>, </code><code>'d'</code><code>: </code><code>4</code><code>}</code>

    抛出異常,是因為傳入的第一個參數1,和第三個參數a=1,都認為是傳入函數參數a了。請注意下這點。

5.4 作用域

作用域聽着挺新鮮,其實很簡單,就是限制一個變量或一段代碼可用範圍,不在這個範圍就不可用。提高了程式邏輯的局部性,減少名字沖突。

作用域範圍一般是:全局(global)-&gt;局部(local)-&gt;内置(build-in)

先看看全局和局部變量:

<code>&gt;&gt;&gt; a </code><code>=</code> <code>2</code>

<code>...   b </code><code>=</code> <code>3</code>

<code>&gt;&gt;&gt; a</code>

<code>2</code>

<code>&gt;&gt;&gt; b</code>

<code>Traceback (most recent call last):</code>

<code>  </code><code>File</code> <code>"&lt;stdin&gt;"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code>&lt;module&gt;</code>

<code>NameError: name </code><code>'b'</code> <code>is</code> <code>not</code> <code>defined</code>

a變量的作用域是整個代碼中有效,稱為全局變量,也就是說一段代碼最開始定義的變量。

b變量的作用域在函數内部,也就是局部變量,在函數外是不可引用的。

這麼一來,全局變量與局部變量即使名字一樣也不沖突。

如果函數内部的變量也能在全局引用,需要使用global聲明:

<code>...   </code><code>global</code> <code>b</code>

<code>3</code>

有報錯,說明一個問題,當函數沒引用使用,裡面的代碼塊是沒有解釋的。

使用global聲明變量後外部是可以調用函數内部的變量的。

5.5 嵌套函數

1)不帶參數

19

20

21

22

23

<code>...   x </code><code>=</code> <code>2</code>

<code>...   </code><code>def</code> <code>func2():</code>

<code>...     </code><code>return</code> <code>x</code>

<code>...   </code><code>return</code> <code>func2  </code><code># 傳回func2函數</code>

<code>&gt;&gt;&gt; func()()</code>

<code>&gt;&gt;&gt; func2()</code>

<code>NameError: name </code><code>'func2'</code> <code>is</code> <code>not</code> <code>defined</code>

<code>&gt;&gt;&gt; </code><code>def</code> <code>func():   </code>

<code>...   x </code><code>=</code> <code>2</code>         

<code>...   </code><code>global</code> <code>func2</code>

<code>...     </code><code>return</code> <code>x </code>

<code>...   </code><code>return</code> <code>func2</code>

内層函數可以通路外層函數的作用域。内嵌函數隻能被外層函數調用,但也可以使用global聲明全局作用域。

調用内部函數的另一種用法:

2)帶參數

<code>&gt;&gt;&gt; </code><code>def</code> <code>func(a):</code>

<code>...   </code><code>def</code> <code>func2(b):</code>

<code>...     </code><code>return</code> <code>a </code><code>*</code> <code>b</code>

<code>&gt;&gt;&gt; f </code><code>=</code> <code>func(</code><code>2</code><code>)   </code><code># 變量指向函數。是的,變量可以指向函數。</code>

<code>&gt;&gt;&gt; f(</code><code>5</code><code>)</code>

<code>10</code>

<code>&gt;&gt;&gt; func(</code><code>2</code><code>)(</code><code>5</code><code>)</code>

内層函數可以通路外層函數的作用域 。但變量不能重新指派,舉例說明:

<code>...      x </code><code>=</code> <code>3</code>

<code>...   func2()</code>

<code>...   </code><code>return</code> <code>x</code>

<code>...     x </code><code>+</code><code>=</code> <code>1</code>

<code>  </code><code>File</code> <code>"&lt;stdin&gt;"</code><code>, line </code><code>5</code><code>, </code><code>in</code> <code>func</code>

<code>  </code><code>File</code> <code>"&lt;stdin&gt;"</code><code>, line </code><code>4</code><code>, </code><code>in</code> <code>func2</code>

<code>UnboundLocalError: local variable </code><code>'x'</code> <code>referenced before assignment</code>

5.6 閉包

“官方”的解釋是:所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。

其實,上面嵌套函數就是閉包一種方式:

func是一個函數,裡面又嵌套了一個函數func2,外部函數傳過來的a參數,這個變量會綁定到函數func2。func函數以内層函數func2作為傳回值,然後把func函數存儲到f變量中。當外層函數調用内層函數時,内層函數才會執行(func()()),就建立了一個閉包。

5.7 高階函數

高階函數是至少滿足這兩個任意中的一個條件:

1) 能接受一個或多個函數作為輸入。

2)輸出一個函數。

abs、map、reduce都是高階函數,後面會講解。

其實,上面所講的嵌套函數也是高階函數。

舉例說明下高階函數:

<code>&gt;&gt;&gt; </code><code>def</code> <code>f(x):</code>

<code>...   </code><code>return</code> <code>x </code><code>*</code> <code>x</code>

<code>&gt;&gt;&gt; </code><code>def</code> <code>f2(func, y):</code>

<code>...   </code><code>return</code> <code>func(y)</code>

<code>&gt;&gt;&gt; f2(f, </code><code>2</code><code>)</code>

<code>4</code>

這裡的f2就是一個高階函數,因為它的第一個參數是一個函數,滿足了第一個條件。

部落格位址:http://lizhenliang.blog.51cto.com

QQ群:Shell/Python運維開發群 323779636

5.8 函數裝飾器

裝飾器(decorator)本身是一個函數,包裝另一個函數或類,它可以讓其他函數在不需要改動代碼情況下動态增加功能,裝飾器傳回的也是一個函數對象。

先舉一個例子,說明下裝飾器的效果,定義兩個函數,分别傳參計算乘積:

<code>#!/usr/bin/python</code>

<code># -*- coding: utf-8 -*-</code>

<code>def</code> <code>f1(a, b):</code>

<code>    </code><code>print</code> <code>"f1 result: "</code> <code>+</code> <code>str</code><code>(a </code><code>*</code> <code>b)</code>

<code>def</code> <code>f2(a, b):</code>

<code>    </code><code>print</code> <code>"f2 result: "</code> <code>+</code> <code>str</code><code>(a </code><code>*</code> <code>b)</code>

<code>f1(</code><code>1</code><code>, </code><code>2</code><code>)</code>

<code>f2(</code><code>2</code><code>, </code><code>2</code><code>)</code>

<code>f1 result: </code><code>2</code>

<code>f2 result: </code><code>4</code>

跟預期的那樣,列印出了乘積。

如果我想給這兩個函數加一個列印傳入的參數,怎麼辦,應該這樣:

<code>    </code><code>print</code> <code>"f1 parameter: %d %d"</code> <code>%</code><code>(a, b)</code>

<code>    </code><code>print</code> <code>"f2 parameter: %d %d"</code> <code>%</code><code>(a, b)</code>

<code>f1 parameter: </code><code>1</code> <code>2</code>

<code>f2 parameter: </code><code>2</code> <code>2</code>

按照所想的列印了傳入的參數,有沒有方法能更簡潔點呢,來看看裝飾器後的效果。

<code>def</code> <code>deco(func):</code>

<code>    </code><code>def</code> <code>f(a, b):</code>

<code>        </code><code>print</code> <code>"%s parameter: %d %d"</code> <code>%</code><code>(func.__name__, a, b)</code>

<code>        </code><code>return</code> <code>func(a, b)</code>

<code>    </code><code>return</code> <code>f</code>

<code>@deco</code>

可見用裝飾器也實作了上面方法,給要裝飾的函數添加了裝飾器定義的功能,這種方式顯得是不是更簡潔呢!

好,那麼我們繼續深入學習裝飾器用法。

   5.8.1 無參數裝飾器

<code>    </code><code>方式</code><code>1</code><code>:函裝飾器函數裝飾函數    </code>

<code>    </code><code>#!/usr/bin/python</code>

<code>    </code><code># -*- coding: utf-8 -*-</code>

<code>    </code><code>def</code> <code>deco(func):</code>

<code>        </code><code>return</code> <code>func</code>

<code>    </code><code>def</code> <code>f1():</code>

<code>        </code><code>print</code> <code>"Hello world!"</code>

<code>    </code><code>myfunc </code><code>=</code> <code>deco(f1)</code>

<code>    </code><code>myfunc()  </code>

<code>    </code><code># python test.py</code>

<code>    </code><code>Hello world!</code>

<code>    </code> 

<code>    </code><code>方式</code><code>2</code><code>:使用文法糖</code><code>"@"</code><code>來裝飾函數</code>

<code>    </code><code>@deco</code>

<code>    </code><code>f1()</code>

   方式1是将一個函數作為參數傳給裝飾器函數。

   方式2使用了文法糖,也實作同樣效果。

   其實兩種方式結果一樣,方式1需要每次使用裝飾器時要先變量指派下,而方式2使用裝飾器時直接用文法糖"@"引用,會顯得更友善些,實際代碼中一般也都是用文法糖。

   2)帶參數裝飾器

<code>    </code><code>#!/usr/bin/python    </code>

<code>        </code><code>def</code> <code>f(a, b):</code>

<code>            </code><code>print</code> <code>"function name: %s"</code> <code>%</code> <code>func.__name__   </code><code># __name__屬性是擷取函數名,為了說明執行了這個函數</code>

<code>            </code><code>return</code> <code>func(a, b)   </code><code># 用接受過來的func函數來處理傳過來的參數</code>

<code>        </code><code>return</code> <code>f</code>

<code>    </code><code>def</code> <code>f1(a, b):</code>

<code>        </code><code>print</code> <code>a </code><code>+</code> <code>b</code>

<code>    </code><code>f1(</code><code>2</code><code>, </code><code>2</code><code>)</code>

<code>    </code><code>function name: f1</code>

   3)不固定參數

<code>    </code><code>def</code> <code>log(func):</code>

<code>        </code><code>def</code> <code>deco(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs):</code>

<code>            </code><code>print</code> <code>"function name: %s"</code> <code>%</code> <code>func.__name__</code>

<code>            </code><code>return</code> <code>func(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>

<code>        </code><code>return</code> <code>deco</code>

<code>    </code><code>@log</code>

<code>        </code><code>print</code> <code>"f1() run."</code>

<code>    </code><code>f1(</code><code>1</code><code>,</code><code>2</code><code>)</code>

<code>    </code><code>f1() run.</code>

    4)裝飾器加參數

<code>    </code><code># 三層函數,調用log函數傳回deco函數,再調用傳回的函數deco,則傳回值是_deco函數</code>

<code>    </code><code>def</code> <code>log(arg):</code>

<code>        </code><code>def</code> <code>deco(func):</code>

<code>            </code><code>def</code> <code>_deco(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs):</code>

<code>                </code><code>print</code> <code>"%s - function name: %s"</code> <code>%</code> <code>(arg, func.__name__)  </code>

<code>                </code><code>return</code> <code>func(</code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>

<code>            </code><code>return</code> <code>_deco</code>

<code>    </code><code>@log(</code><code>"info"</code><code>)</code>

<code>    </code><code>info </code><code>-</code> <code>function name: f1</code>

    再舉一個例子,給函數輸出字元串帶顔色:

<code>    </code><code>def</code> <code>fontColor(color):</code>

<code>        </code><code>begin </code><code>=</code> <code>"\033["</code>

<code>        </code><code>end </code><code>=</code> <code>"\033[0m"</code>

<code>        </code><code>d </code><code>=</code> <code>{</code>

<code>            </code><code>'red'</code><code>:</code><code>'31m'</code><code>,</code>

<code>            </code><code>'green'</code><code>:</code><code>'32m'</code><code>,</code>

<code>            </code><code>'yellow'</code><code>:</code><code>'33m'</code><code>,</code>

<code>            </code><code>'blue'</code><code>:</code><code>'34m'</code>

<code>        </code><code>}</code>

<code>            </code><code>print</code> <code>begin </code><code>+</code> <code>d[color] </code><code>+</code> <code>func() </code><code>+</code> <code>end</code>

<code>    </code><code>@fontColor(</code><code>"red"</code><code>)</code>

<code>    </code><code>def</code> <code>f():</code>

<code>        </code><code>return</code> <code>"Hello world!"</code>

<code>    </code><code>@fontColor(</code><code>"green"</code><code>)</code>

<code>    </code><code>def</code> <code>f2():</code>

   可以看出裝飾器處理方式滿足了高階函數的條件,是以裝飾器也是一種高階函數。

   優點:靈活給裝飾器增加功能,而不修改函數,提高代碼可重複利用性,增加可讀性。

5.9 匿名函數

匿名函數:定義函數的一種形式,無需定義函數名和語句塊,是以代碼邏輯會受到局限,同時也減少代碼量,增加可讀性。

在Python中匿名函數是lambda。

舉例子說明def關鍵字與lambda函數定義函數差別:

<code># 普通函數</code>

<code>...   </code><code>return</code> <code>"Hello world!"</code>

<code>&gt;&gt;&gt; </code><code>def</code> <code>func(a, b):</code>

<code>...   </code><code>return</code> <code>a </code><code>*</code> <code>b</code>

<code>&gt;&gt;&gt; func(</code><code>2</code><code>, </code><code>2</code><code>)</code>

<code># 匿名函數</code>

<code>&gt;&gt;&gt; f </code><code>=</code> <code>lambda</code><code>:</code><code>"Hello world!"</code>

<code>&gt;&gt;&gt; f()</code>

<code>&gt;&gt;&gt; f </code><code>=</code> <code>lambda</code> <code>a, b: a </code><code>*</code> <code>b   </code><code># 冒号左邊是函數參數,右邊是傳回值</code>

<code>&gt;&gt;&gt; f(</code><code>2</code><code>, </code><code>2</code><code>)</code>

lambda函數一行就寫成一個函數功能,省去定義函數過程,讓代碼更加精簡。

5.10 内置高階函數

   5.10.1 map()

   文法:map(function, sequence[, sequence, ...]) -&gt; list

   将序列中的元素通過函數處理傳回一個新清單。

   例如:

<code>    </code><code>&gt;&gt;&gt; lst </code><code>=</code> <code>[</code><code>1</code><code>,</code><code>2</code><code>,</code><code>3</code><code>,</code><code>4</code><code>,</code><code>5</code><code>]    </code>

<code>    </code><code>&gt;&gt;&gt; </code><code>map</code><code>(</code><code>lambda</code> <code>x:</code><code>str</code><code>(x)</code><code>+</code><code>".txt"</code><code>, lst)</code>

<code>    </code><code>[</code><code>'1.txt'</code><code>, </code><code>'2.txt'</code><code>, </code><code>'3.txt'</code><code>, </code><code>'4.txt'</code><code>, </code><code>'5.txt'</code><code>]</code>

   5.10.2 filter()

   文法:filter(function or None, sequence) -&gt; list, tuple, or string

   将序列中的元素通過函數處理傳回一個新清單、元組或字元串。

   例如:過濾清單中的奇數

<code>    </code><code>&gt;&gt;&gt; </code><code>filter</code><code>(</code><code>lambda</code> <code>x:x</code><code>%</code><code>2</code><code>=</code><code>=</code><code>0</code><code>, lst)</code>

<code>    </code><code>[</code><code>2</code><code>, </code><code>4</code><code>]</code>

   5.10.3 reduce()

   文法:reduce(function, sequence[, initial]) -&gt; value

   reduce()是一個二進制運算函數,是以隻接受二進制操作函數。

   例如:計算清單總和

<code>    </code><code>&gt;&gt;&gt; </code><code>reduce</code><code>(</code><code>lambda</code> <code>x,y:x</code><code>+</code><code>y, lst)</code>

<code>    </code><code>15</code>

    先将前兩個元素相加等于3,再把結果與第三個元素相加等于6,以此類推。這就是reduce()函數功能。

本文轉自 李振良OK 51CTO部落格,原文連結:http://blog.51cto.com/lizhenliang/1856793,如需轉載請自行聯系原作者