この章の内容を説明する前に、私たちは、数学の問題を調べてどのように多くの正の整数解次方程式を言いますよ。
実際には、上記の問題は、プログラムの種類の少なくとも数リンゴアップルの4組に分け8に相当します。答えはかなり明確である。この問題を考えます。
以下のコードに示すように、プログラムは、Pythonの値を計算するために使用することができます。
"""
输入M和N计算C(M,N)
Version: 0.1
Author: 骆昊
"""
m = int(input('m = '))
n = int(input('n = '))
fm = 1
for num in range(1, m + 1):
fm *= num
fn = 1
for num in range(1, n + 1):
fn *= num
fmn = 1
for num in range(1, m - n + 1):
fmn *= num
print(fm // fn // fmn)
関数のリターンは
あなたが気づいた場合は、上記のコードでは、我々は3回階乗を行い、このコードは実際には重複したコードであるかわかりません。氏はMartin Fowler氏がかつて言ったマスタープログラマー:「!多くの悪趣味・コードがありますが、繰り返しは最悪の一種である」、解決すべき高品質なコード最初の問題を記述するには、コードを繰り返すことです。上記のコードの場合、私たちは「機能」の機能モジュール、必要な階乗計算にカプセル化された階乗関数呼び出しを計算することができ、我々は唯一の「呼び出し」その上に「機能」にする必要があります。
定義された関数は、
各関数として関数や変数を定義するキーワードdefをPythonで使用することができますも有名な名前を持っていますが、変数の命名規則と命名は一致しています。関数のパラメータ、この上の機能や数学に置かれ、関数名の後の括弧内に渡すことができ、プログラムの関数のパラメータが非常に似ている関数の数学的な引数を言うに相当し、機能の実行は、我々が完了できていますreturnキーワードによってその従属変数の数学関数を言うと同等である値を返します。
関数を定義する方法の理解では、我々は、上記のコードの再構築を行うことができ、いわゆる再構成は、コードの実行結果の前提を調整するためのコードの構造に影響を与えることなく、復興後のコードを以下に示しています。
def factorial(num):
"""求阶乘"""
result = 1
for n in range(1, num + 1):
result *= n
return result
m = int(input('m = '))
n = int(input('n = '))
# 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数
print(factorial(m) // factorial(n) // factorial(m - n))
説明:Pythonの数学モジュールがすでに階乗関数であるが、実際には、この既製自分の定義なし階乗関数を計算するために直接使用することができます。次の例では、Pythonの関数のいくつかはまた、容易に入手可能である、我々は関数の定義および使用を説明するためにここにいるだけにして、彼らは再び実現され、実際の開発では、この低レベルの反復作業を行うことをお勧めしません。
関数のパラメータの
機能に有意な差は、Pythonのためにある多くの場所が残っているプログラミング言語の大部分は「ビルディング・ブロック」によってサポートされていることをコードではなく、言語の他の機能とのPythonの機能は同じではありません関数のパラメータを処理します。私たちは、時間の関数の定義が異なる様々な、それを作ることができるので、Pythonは、他の言語は関数のオーバーロードをサポートするようにする必要はありませんので、Pythonでは、関数のパラメータは、デフォルト値を持っているだけでなく、可変パラメータの使用をサポートすることができます使用、次のように二つの小さな一例です。
from random import randint
def roll_dice(n=2):
"""摇色子"""
total = 0
for _ in range(n):
total += randint(1, 6)
return total
def add(a=0, b=0, c=0):
"""三个数相加"""
return a + b + c
# 如果没有指定参数那么使用默认值摇两颗色子
print(roll_dice())
# 摇三颗色子
print(roll_dice(3))
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
# 传递参数时可以不按照设定的顺序进行传递
print(add(c=50, a=100, b=200))
パラメータはデフォルト値、手段に設定されている上に私たちは2つの機能を与え、あなたがこのパラメータのデフォルト値を使用している場合であれば、対応するパラメータの値がno着信機能、上記のコードでは、私たちはそう彼らは他の多くの言語がオーバーロード効果は同じである関数のように関数呼び出しを追加するためのさまざまな方法、さまざまなを使用することができます。
実際には、上記の追加機能だけでなく、より良い実装は、我々は、ゼロ以上のパラメータの加算器を持っている可能性があるため、呼び出し側によって決定されているどのように多くのパラメータ、我々はデザイナー、この点として機能し、具体的パラメータの数は、我々は、可変パラメータ、以下のコードを使用することができたときに、その不確実な何も知りません。
# 在参数名前面的*表示args是一个可变参数
def add(*args):
total = 0
for val in args:
total += val
return total
# 在调用add函数时可以传入0个或多个参数
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7, 9))
機能を備えた管理モジュール
の任意のプログラミング言語のため、我々はこの命名の競合厄介な状況が発生しますので、変数に、名前から機能な識別子は、頭の痛い問題です。最も単純なシナリオでは、Pythonは関数のオーバーロードの概念がないので、後者の定義は定義をカバーする前に、そして、それは2つの機能は、実際には同じ名前の関数であることを意味し、同じの.pyファイル内に同じ名前の2つの関数の定義であるのみ1が存在します。
def foo():
print('hello, world!')
def foo():
print('goodbye, world!')
# 下面的代码会输出什么呢?
foo()
もちろん、上記の場合は、我々は簡単に回避することができるが、それはコラボレーション以上のチームによって開発されたプロジェクトを遂行するための時間であれば、チームはより多くのプログラマは、このネーミングを解決するためにどのようにして、fooという名前の関数を定義していてそれを競合?答えは、各ファイルはモジュール(モジュール)を表し、我々はモジュールが最後に区別することができ、指定importキーワードによってインポート機能を使用する場合、我々は、異なるモジュールで同じ名前の関数を持つことができ、Pythonの非常に簡単ですどのモジュール関数fooを使用して、コードのルックスが好きです。
module1.py
def foo():
print('hello, world!')
module2.py
def foo():
print('goodbye, world!')
test.py
from module1 import foo
# 输出hello, world!
foo()
from module2 import foo
# 输出goodbye, world!
foo()
最終用途の関数fooに示すような方法を区別することができます。
test.py
import module1 as m1
import module2 as m2
m1.foo()
m2.foo()
コードは次のように書かれている場合は、インポートのfoo fooは以前にインポート覆っしかし、プログラムは、最後のfoo輸入に呼ばれています。
test.py
from module1 import foo
from module2 import foo
# 输出goodbye, world!
foo()
test.py
from module2 import foo
from module1 import foo
# 输出hello, world!
foo()
私たちならば、実際には、我々はそう願っていないことが、私たちはそこにコードを実行することができ、関数の定義に加えて、モジュールをインポートする場合は、モジュールをインポートするときに、その後、Pythonインタプリタがコードを実行し、ことに留意すべきです直接モジュールを実行するようにしない限り条件下コードが原因でのみ直接実行モジュール、実装されない場合に書かれたコードモジュールを実行し、以下に示すような状態にこのコードを実行することが好ましいです。名前は「あるメイン。」
module3.py
def foo():
pass
def bar():
pass
# __name__是Python中一个隐含的变量它代表了模块的名字
# 只有被Python解释器直接执行的模块的名字才是__main__
if __name__ == '__main__':
print('call foo()')
foo()
print('call bar()')
bar()
test.py
import module3
# 导入module3时 不会执行模块中if条件成立时的代码 因为模块的名字是module3而不是__main__
注:あなたは私たちが定義する必要がある理由である、我々は機能を抽出するためのコードと、比較的独立した機能を繰り返したとき、私たちはより複雑な問題を解決するために、これらの機能を組み合わせることができ、上記の手順で表示され、使用することができますその理由の非常に重要な機能。
最後に、我々は、Pythonの変数のスコープに関連する問題を議論します。
def foo():
b = 'hello'
# Python中可以在函数内部再定义函数
def bar():
c = True
print(a)
print(b)
print(c)
bar()
# print(c) # NameError: name 'c' is not defined
if __name__ == '__main__':
a = 100
# print(b) # NameError: name 'b' is not defined
foo()
上記のコードが正常に実行され、プリントアウト100、ハローと確かに、私たちが気づいていることができ、定義されていないaとbは、aとbからあり、機能バー内の二つの変数です。我々はグローバル変数(グローバル変数)である変数A、上記のコードに分岐を定義する場合、それがいずれかの関数で定義されていないため、グローバルスコープに属します。上記では、ローカル範囲に属する、関数定義内のローカル変数である関数foo変数B、(ローカル変数)を定義し、外部の関数fooは、それへのアクセスを持っていないが、内部関数fooバーこの関数は、変数bは、ネストされたスコープは、我々はそれにアクセスすることができますバーの機能である属します。機能バーに加えて、ローカルの範囲cが属するバー内の変数は、アクセスできません。実際には、我々は上記のコードで見てきた最初の3「ローカルスコープ」、Pythonは変数「グローバルスコープ」を検索すると秩序「ビルトインスコープ」を探し、「ネストされたスコープ」、の順いわゆる「ビルトインスコープ」に内蔵された範囲に属する組み込みのPythonのこれらの識別子は、我々が以前に使用した入力、印刷、intです。
以下のコードを見て、私たちは、関数呼び出しでグローバル変数の値を変更したいのですが、実際には次のコードではありません。
def foo():
a = 200
print(a) # 200
if __name__ == '__main__':
a = 100
foo()
print(a) # 100
あなたが関数fooを呼び出した後、我々は関数fooに200を=書くとき、ローカル変数の名前の再定義は、それがグローバルスコープであるので、我々はまだ100の値は、これがあることを見つけますていないため、その変数の同じ変数、ローカルスコープ、およびのため、もはや検索関数fooグローバルスコープ。我々はスコープのfoo関数内でグローバル変更したい場合は、コードを以下に示します。
def foo():
global a
a = 200
print(a) # 200
if __name__ == '__main__':
a = 100
foo()
print(a) # 200
私たちは、その後、次のコード行は、変数を定義し、グローバルスコープを配置しますグローバルスコープ、そうでない場合は、グローバルスコープから変数foo関数であることを示すために、グローバルなキーワードを使用することができます。私たちは関数内の関数は、変数のネストされたスコープを変更することができますしたい場合は同様に、ネストされたスコープ、してください自己テストからローカル以外の変数を示すためにキーワードを使用することができます。
実際の開発では、我々は、グローバル変数の使用を最小限に変更し、予想外の使用グローバル変数のスコープと影響が広すぎるので、発生する可能性がありますする必要があり、グローバル変数に加えて、ローカル変数よりも長いを持っていますオブジェクトによって占有メモリが長時間になる可能性があり、ライフサイクルは、ゴミにすることはできません。実際には、グローバル変数の使用を減らすこと、また、コード間の結合度を低減するための重要な尺度でなく、デメテルの実践です。最後に、それはあなたがまだその値を使用することができ、関数呼び出しの定義だそうことを、私たちは関数内の変数のスコープを作成しようとする必要があり、グローバル変数の手段の使用を減らして、私たちは、ローカル変数のライフサイクル延長をしたい場合この時間は、私たちは、その後の内容で説明クロージャを、使用する必要があります。
説明:多くの人々はしばしば、「閉鎖」と「無名関数は、」混乱しますが、実際に彼らはあなたがこの概念を理解したいならば、あなたはウィキペディアを見てか、平和の概念上の議論の知識を取ることができ、同じものではありません。
彼は、結論は簡単ですので、多くの、実際には、我々は次の形式でこれからPythonコードを書くことができ、我々の理解の改善のこの少しは実際に基本的な機能と範囲で大きな前進であると述べました。
def main():
# Todo: Add your code here
pass
if __name__ == '__main__':
main()