PYベーシス・ポイントの検査
PY言語機能
pyがダイナミック強く型付けされた言語です
- これは、タイプを判別動的または静的コンパイル時または実行時のことをいいます
暗黙の型に対して強く型付けを指しインストールは発生しません
なぜPY?
* 胶水语言,轮子多,应用广泛
* 语言灵活,生产力高
* 性能问题,代码维护问题,py2/py3不兼容
ダックタイピングとは何ですか?
- あなたは、鳥はアヒルのように歩き参照アヒルのように泳ぎ、アヒルのように鳴くときは、この鳥はアヒル呼び出すことができる
オブジェクトの振る舞いのフォーカスポイントではなく、タイプ(ダックタイピング)
EG:ファイル、たStringIO、ソケットオブジェクトは、読み取り/書き込み方法サポートする
別の例は、オブジェクト定義__iter__マジック方法は、インタフェースの種類ではなく、タイプについて心配反復アヒルのために使用することができるされている(オブジェクトのようなファイル)
class Duck:
def quack(self):
print("gua gua")
class Person:
def quack(self):
print("我是人类, 但我也会guo guo guo")
def in_the_forest(duck):
duck.quack()
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
print(type(donald))
print(type(john))
print(isinstance(donald, Duck))
print(isinstance(john, Person))
game()
1はそれを使用するモンキーパッチは?何ですか?どのように実現しますか?
- いわゆるモンキーパッチは、実行時に置き換えることです
//eg:gevent库需要修改内置的socket
from gevent import monkey; monkey.patch_socket()
import socket
print(socket.socket)
print("After monkey patch")
from gevent import monkey
monkey.patch_socket()
print(socket.socket)
import select
print(select.select)
monkey.patch_select()
print("After monkey patch")
print(select.select)
import time
print(time.time())
def _time():
return 1234
time.time = _time
print(time.time())
イントロスペクションとは何ですか?
内観
オブジェクトの型情報の取得でisinstance、能力、タイプとPYすべてのオブジェクト、IDのオブジェクトの実行時の型を決定します
検査モジュールは、オブジェクト情報へのより大きなアクセスする機能を提供
ll = [1, 3, 3] d = dict(a=1) #{a:1} print(type(ll)) print(type(d)) print(isinstance(ll, list)) print(isinstance(d, dict)) def add(a, b): if isinstance(a, int): return a + b elif isinstance(a, str): return a.upper() + b print(add(1, 2)) print(add('head', 'tail')) print(id(ll)) print(id(d)) print(ll is d) print(ll is ll)
リストや辞書の導出は何ですか
リスト内包
'''[i for i in range(10) if i % 2 == 0]
一种快速生成list/dict/set的方式。用来替代map/filter等
(i for i in range(10) if i % 2 == 0) 返回生成器'''
eg:
a = ['a', 'b', 'c']
b = [1, 2, 3]
d = {}
for i in range(len(a)):
d[a[i]] = b[i]
print(d)
d = {k: v for k, v in zip(a, b)}
print(d)
# !< output
{'a': 1, 'b': 2, 'c': 3}
{'a': 1, 'b': 2, 'c': 3}
eg:
l = [i for i in range(10)]
print(l)
print(type(l))
l = (i for i in range(10))
print(type(l))
for i in l:
print(i)
発電機を使用すると、大幅にメモリを節約することができます
PY禅
import this
PY2 / 3の違い定期試験
- Pythonのバージョンを使用しpyenvインストール
PY3の改善
印刷の関数として、
問題のコーディング、PY3もはやユニコードオブジェクトは、デフォルトではUnicodeのstrのです
課の変更、PY3分割記号および浮動小数点
5/2 = 2.5
5 // 2 = 2
IDEの型チェックを達成するのを助けるための型注釈(タイプヒント)
def hello(name: str)->str:
return "hello" + name
print(hello("laowang"))
最適化されたスーパー()関数は、親クラスの直接呼び出しを容易にするために、
高度アンパック操作、A、B、* RET =範囲(10)
a, b, *c = range(10)
print(a)
print(b)
print(c)
a, b, *_ = range(10)
print(a)
print(b)
#后面没有数字被舍弃
PY3が改善
定義されたキーワード引数キーワード引数だけを
EGを:
#は、主要なパラメータは、パラメータ名塊の参加を指定する必要が定義
def add(a, b, *, c):
return a + b +c
print(add(1, 2, c = 3))
スタック情報失うことなく、連鎖例外PY3の再スローを
予約済みの例外スタック情報から#raiseを
すべてはイテレータを返します
range, zip, map, dict.values,etc
are all iterators
PY3新しい
子プロデューサーのリンクから*収量
* asyncio内置库, async/await 原生协程支持异步编程
新的内置库enum, mock, asyncio, ipaddress, concurrent.futures等
PY3の改善
- PYCファイル等ビルトインライブラリの変更、urlib、セレクタの一部を__pycache__統一生成しました
- パフォーマンスの最適化
互換性のあるツールのいくつかの三分の二
6つのモジュール
なトランスコーディングなどPY3ツールへPY2
__future__
PY質問は、多くの場合、機能し
、通常のテストサイトを
渡されたパラメータ
(なし)変数オブジェクトの
変数のパラメータを
次のコードの出力は何でしたか?
* 可变类型作为参数
def flist(l):
l.append(0)
print(l)
l = []
flist(l)
flist(l)
# !< out:
[0]
[0, 0]
- パラメータとして不変タイプ
def fstr(s):
s += 'a'
print(s)
s = "hehe"
fstr(s)
fstr(s)
# !< out:
"hehea"
"hehea"
パラメータを渡す方法をPY
混乱質問は
値を渡すか、それを参照?どちらもありません。唯一のパラメータの受け渡しは、共有質量参加によって支持されている
オブジェクトによってコール(オブジェクト参照または共有することにより、コールによってコール)
各引数のコピーを入手する機能パラメータを(共有パラメータ渡し)を共有することにより、コールは、引用された
PYすべてがオブジェクトであります
PY変数/不変オブジェクトは
変数を知るようにと不変のビルトインは、関数パラメータの副作用理解する上で有益なオブジェクト
変数と不変オブジェクトですか?
不可变对象 bool/int/float/tuple/str/frozenset
可变对象 list/set/dict
def clear_list(l):
l = []
ll = [1, 2, 3]
clear_list(ll)
print(ll)
デフォルトパラメータデフォルトパラメータの計算などを念頭に置いPY可変パラメータ一度だけ
def flist(l = [1]):
l.append(l)
print(l)
fl()
fl()
PY *引数** kwargsから
ファンクションの配信* argsを、** kwagsは意味しますか?
変数パラメータを処理するための
*引数はタプルにパックされています
** kwargsからは、辞書にパックされています
def print_multiple_args(*args):
print(type(args), args)
for idx, val in enumerate(args):
print(idx, val)
print_multiple_args('a', 'b', 'c')
print_multiple_args(*['a', 'b', 'c'])
# !< out:
<class 'tuple'> ('a', 'b', 'c')
0 a
1 b
2 c
def print_kwargs(**kwargs):
print(type(kwargs))
for k, v in kwargs.items():
print('{}: {}'.format(k, v))
print_kwargs(a=1, b=2)
print_kwargs(**dict(a=1, b=2))
# !< out:
<class 'dict'>
a: 1
b: 2
def print_all(c, *args, **kwargs):
print(c)
if args:
print(args)
if kwargs:
print(kwargs)
print_all(1, "hello", a="muke")
1
('hello',)
{'a': 'muke'}
PY例外メカニズムが多い質問
PY例外とは何ですか?
PYは、例外処理エラー(いくつかの言語のエラーコード)を使用する
BaseException
SystemExitを/ KeyboardInterrupt / GeneratorExit
例外
異例の一般的なシナリオを使用します
とき私は、ハンドルの例外をキャプチャする必要がありますか?内蔵された異常の種類PY見て
ネットワーク要求(タイムアウト、接続エラーなど)
リソースへのアクセス(権問題、資源が存在しません)
コードのロジック(踏み、KeyError例外など)
異常PYに対処する方法
いくつかのキーワードを知ろう
try:
#func #可能会抛出异常的代码
except (Exception1, Exception 2) as e: #可以捕获多个异常并处理
#异常处理的代码
else:
#pass #异常没有发生的时候代码逻辑
finally:
#pass #无论异常有没有发生都会执行的代码, 一般处理资源的关闭和释放
どのようにカスタム例外
独自の例外をカスタマイズする方法?なぜ我々は独自の例外を定義する必要がありますか?
カスタム継承された異常(なぜBaseException)を実装するための例外
を除いプラスいくつかの追加情報に
いくつかの特定のビジネス関連の異常に対処する(MyExceptionを上げます)
class MyException(Exception):
pass
try:
raise MyException('my exception')
except MyException as e:
print(e)
PYパフォーマンス分析と最適化、GILは、多くの場合、試験
GILはCPythonとは何ですか
GIL ,,株式会社参加無料インタプリタロック
メモリ管理はスレッドセーフCPythonのインタプリタではありません
Pythonのマルチスレッドの保護の下でオブジェクトへのアクセス
単純なロック機構を使用して、CPythonの複数のスレッドは、バイトコードを実行回避
GILの影響
プログラムのマルチコア実行を制限するために、
1つのスレッドだけバイトコードの実行と同時に
、マルチコアの利点使用するCPU集約型のプログラムが困難
GIL IOの間にリリースされますが、IOの集中プログラムはへの影響はほとんどあり
GILの影響を回避する方法
CPUとIO集約型のプログラムを区別し
あなたは、マルチプロセスCPU集約型のプロセスプール+使用することができ
、マルチスレッドのIO集中的に使用/コルーチンを
拡大CPythonと
GILを達成するために
# 请问这段代码输出?
import threading
n = [0]
def foo():
n[0] = n[0] + 1
n[0] = n[0] + 1
threads = []
for i in range(5000):
t = threading.Thread(target=foo)
threads.append(t)
for t in threads:
t.start()
print(n)
# !< 加锁操作
import threading
lock = threading.lock()
n = [0]
def foo():
with lock:
n[0] = n[0] + 1
n[0] = n[0] + 1
threads = []
for i in range(5000):
t = threading.Thread(target=foo)
threads.append(t)
for t in threads:
t.start()
print(n)
なぜGILまた、スレッドの安全性を懸念していますか?
オペレーティングPY原子は何ですか?
ワンステップ実行
原子を完成させることができるバイトコード命令場合、操作を
原子するスレッドセーフであることができる
バイトコードDISの動作を分析するために使用
なぜGILまた、スレッドの安全性が心配?
#原子操作
import dis
def update_list(l):
l[0] = 1 #原子操作, 不用担心线程安全问题
#dis.dis(update_list)
"""
280 0 LOAD_CONST 1 (1)
2 LOAD_FAST 0 (l)
4 LOAD_CONST 2 (0)
6 STORE_SUBSCR #单字节码操作,线程安全
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
"""
#非原子操作 不是线程安全
def incr_list(l):
l[0] += 1 #危险!!不是原子操作
dis.dis(incr_list)
"""
295 0 LOAD_FAST 0 (l)
2 LOAD_CONST 1 (0)
4 DUP_TOP_TWO
6 BINARY_SUBSCR
8 LOAD_CONST 2 (1)
10 INPLACE_ADD #需要多个字节码操作, 有可能在线程执行
#过程中切到其它线程
12 ROT_THREE
14 STORE_SUBSCR
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
"""
プログラムのパフォーマンスを分析する方法を
プロファイルツールのさまざまな方法を使って(内蔵またはサードパーティ)
- 八の法律は、ほとんどの時間は、少量のコードを引き受けました
- 内蔵のプロフィール/ cprofileおよびその他のツール
- pyflame(ユーバーオープン)炎の描画ツールを使用します
サーバーのパフォーマンスの最適化対策
、Webアプリケーションの一般的な言語がボトルネックになっていません
- データ構造とアルゴリズム
- データベース層:インデックスチューニングスロークエリは、IOを削減するバッチ操作を排除し、NoSQLの
- ネットワークIO:バッチ処理、パイプライン動作は、IOを減らすために
- キャッシュ:使用メモリデータベースのRedisの/ memcachedの
- 非同期:セロリasyncio
- 同時実行:gevent /マルチスレッド
コルーチンとPYジェネレータ
ジェネレータ
- やりがいのある関数を生成するジェネレータ
- この関数はyieldキーワード発電機となっている場合には
- 発電機は、現在実行状態と遺骨の実行を停止することができます
ビルダーとは何ですか
def simple_gen():
yield 'hello'
yield 'world'
gen = simple_gen()
print(type(gen)) #'generator' object
print(next(gen)) #'hello'
print(next(gen)) #'world'
ベースの発電機のコルーチン
PY3なしネイティブコルーチンコルーチンの前にのみ発電機ベースの
pep342(拡張ジェネレータを経由してコルーチン)強化ファンクションジェネレータ
生成器可以通过yield暂停执行和产出数据
発電への支援の送信は、()(データとスロー・ジェネレータを送る)例外
# !< Generator Based Coroutine
def coro():
hello = yield 'hello' #yield关键字在右边作为表达式, 可以被send值
yield hello
c = coro()
#输出'hello' 这里调用next产出第一个值'hello', 之后函数暂停
print(next(c))
#再次调用send发送值 此时hello变量赋值为'world' 之后yield产出hello变量的值'world'
print(c.send('world'))
#之后协程结束, 后续再send值会抛异常StopIteration
注意事項コルーチン
コルーチンを開始するウォルフプライムに(なし)または次(コルーチン)を送信しないする必要が
中断するコルーチンの収率で
呼び出し元に出力値の値が得られる個々の
coroutine.send(値)コルーチン値に送信する、送信された値は、の左に変数降伏式に代入されます
値=利回り
コルーチン実行後は、(yield文に遭遇していない)完全で呼び出すとStopIterationが発生します
コルーチンデコレータは
センドそれウォルフたびに回避しました
from functools import wraps
def coroutine(func): #不用每次都用send(None)启动
"""装饰器:向前执行到第一个'yield'表达式,预激`func`"""
@wraps(func)
def primer(*args, **kwargs):
gen = func(*args, **kwargs)
next(gen)
return gen
return primer
PY3ネイティブコルーチン
py3.5導入非同期/のawaitサポートコルーチンのネイティブ(ネイティブコルーチン)
import asyncio
import datetime
import random
async def display_date(num, loop):
end_time = loop.time() + 50.0
while True:
print('Loop: {} Time: {}'.format(num, datetime.datetime.now()))
if(loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(random.randint(0, 5))
loop = asyncio.get_event_loop()
asyncio.ensure_future(display_date(1, loop))
asyncio.ensure_future(display_date(2, loop))
loop.run_forever()
ユニットテスト
ユニットテストは何
のユニットテスト
用のプログラムモジュールの正しさを検証するための
機能、検証されるクラス
のプログラムの正しさを保証するために、下から上
なぜライトユニットテスト
3望ましくないコード(NO文書、無登録、単一のテスト)
- コード・ロジック(およびテスト駆動開発(TDD)の一部であっても使用)の正しさを保証するために
- 単一プローブ設計の影響、コードを測定することは容易では多くの場合、非常に粘着性の結合であります
- 回帰テストは、全体のサービスが利用できない変化を防止するために
ユニットテスト関連のライブラリ
- より一般的に鼻/ pytest
- あるいは模擬モジュールは、ネットワーク等の要求をシミュレートするために使用します
- カバレッジ統計的テストカバレッジ
def binary_search(array, target):
if not array:
return -1
beg, end = 0, len(array)
while beg < end:
mid = beg + (end - beg) // 2 #py3
if array[mid] == target:
return mid
elif array[mid] > target:
end = mid
else:
beg = mid + 1
return -1
def test():
"""
如何设计测试用例:等价类划分
- 正常值功能测试
- 边界值(eg 最大最小, 最左最右值)
- 异常值(eg None, 空值, 非法值)
:return:
"""
#正常值, 包含有和无两种结果
assert binary_search([0, 1, 2, 3, 4, 5], 1) == 1
assert binary_search([0, 1, 2, 3, 4, 5], 6) == -1
assert binary_search([0, 1, 2, 3, 4, 5], -1) == -1
#边界值
assert binary_search([0, 1, 2, 3, 4, 5], 0) == 0
assert binary_search([0, 1, 2, 3, 4, 5], 5) == 5
assert binary_search([0], 0) == 0
# #异常值
assert binary_search([], 1) == -1
#pip install pytest
#pytest xx.py
PY深い浅いコピーコピー
深いコピーとの間の差のシャローコピー
深いコピーである何?シャローコピーとは何ですか?
ディープコピーを達成するためにどのようにPY?