$30 off During Our Annual Pro Sale. View Details »

ざっとわかるPython

 ざっとわかるPython

hakobe (Yohei Fushii)

November 03, 2017
Tweet

More Decks by hakobe (Yohei Fushii)

Other Decks in Programming

Transcript

  1. ͬ͟ͱΘ͔Δ
    Python
    hakobe

    View Slide

  2. ൃදͷഎܠ
    • ͍ΖΜͳݴޠΛదࡐదॴͰ࢖͍͜ͳ͍ͨ͠

    ΋ͷͰ͢Ͷ
    • Pythonʹ੎͍͕͋ΔͷͰ࢖͑ΔΑ͏ʹͳͬ
    ͯΔͱศརͦ͏
    • ͬ͘͟Γௐ΂ͨͷͰͬ͘͟Γ঺հ͠·͢

    View Slide

  3. Python (ͬ͘͟Γ)
    • ൚༻εΫϦϓτݴޠ
    • ΠϯσϯτͰΞϨ͢Δ΍ͭ
    • 2ͱ3͕͋Δ
    • ࠷ۙΘΓͱਓؾ͕͕͋ͬͯΔ

    View Slide

  4. Python
    class Blog():
    def __init__(self, id, owner_id, title):
    self.id = id
    self.owner_id = owner_id
    self.title = title
    def is_owned_by(self, user):
    return user.id == self.owner_id

    View Slide

  5. ࠓ೔ͷΰʔϧ: 

    Pythonͷงғؾ͕ͬ͟ͱΘ͔Δ
    ˒ ։ൃ؀ڥ
    ˒ Web։ൃ
    ˒ σʔλ෼ੳ
    ˒ ݴޠͷਐԽ
    ˒ ίϛϡχςΟ

    View Slide

  6. ։ൃ؀ڥ

    View Slide

  7. Python 2? 3?
    • Python3 Λ࢖͑͹OK
    • ۙ೥ϥΠϒϥϦ΋ἧ͖ͬͯͨ
    • Python2ܥ͸2020೥Ͱऴྃ
    • 2.7ܥ͕࠷ޙͷϦϦʔε

    View Slide

  8. Python3 Unicodeจࣈྻ ໰୊
    1. ৗʹ use utf8; ͞ΕΔΑ͏ʹͳͬͨ(Perl೴
    2. จࣈྻͱόΠτྻΛ·ͥΔͱྫ֎ʹͳΔ
    • ݕࡧΩʔϫʔυ: “python3 unicode ͳͥ”

    View Slide

  9. Python3ͷจࣈྻͷߟ͑ํ
    • ೖྗΛdecode/ग़ྗΛencode(஌ͬͯΔ΍
    ͭ!
    # 外部からの入力はバイト列
    in_bytes = b'\xf0\x9f\x8d\xa3'
    string = in_bytes.decode('utf-8')
    # バイト列にして外部に出力
    out_bytes = string.encode('utf-8')

    View Slide

  10. खݩ؀ڥͷߏங
    • ݕࡧΩʔϫʔυ: “Python yamaguchi 2017”
    • ʙ؆୯3εςοϓʙ
    • pyenvͰॲཧܥΛ͍ΕΔ
    • python -m venv Ͱ؀ڥ੾Γସ͑Δ
    • pip ͰϥΠϒϥϦΛΠϯετʔϧ͢Δ
    ͿͬͪΌ͚ॾઆ͋Δ͚ͲखݩͰ͸͜ΕͰշద

    View Slide

  11. ϥΠϒϥϦ
    • ඪ४ϥΠϒϥϦ
    • Battery Included ํࣜͰॆ࣮
    • https://docs.python.jp/3/library/
    • CPANతͳ΍ͭ = PyPI
    • ඪ४ͷpip ίϚϯυͰΠϯετʔϧͰ͖Δ

    View Slide

  12. PyPI

    View Slide

  13. ΤσΟλ
    • ͍͍ͩͨPythonαϙʔτ͕͋ͬͯ҆৺
    • ྑ͍IDE΋͋Δ: PyCharm
    • ࠷ۙࣗ෼͸Visual Studio CodeΛ࢖ͬͯΔ
    • linter΍ิ׬͕͙͢࢖͑ͯศར

    View Slide

  14. Linter
    • flake8Λ࢖͑͹͍͍ͩͨOK
    • ΍ͨΒLinterతϥΠϒϥϦ͕ଟ͍
    • pycodestyle, pydocstyle, pyflake, flake8,
    hacking …
    • autopep8 ॻ͖׵͑ͯ͘ΕΔ΍ͭ΋͋Δ

    View Slide

  15. flake8
    • pycodestyle + pyflake
    > flake8 enjoy.py
    enjoy.py:1:1: F401 'os' imported but unused
    enjoy.py:3:1: E302 expected 2 blank lines, found 1
    enjoy.py:4:5: F841 local variable 'i' is assigned to but never used
    enjoy.py:9:5: E303 too many blank lines (2)

    View Slide

  16. Test
    VOJUUFTU ඪ४ఴ෇ɺඞཁे෼
    QZUFTU ׆ൃɺΑ͘࢖ΘΕͯΔɺQPXFSBTTFSU
    OPTF ੲ͸੎͍͕͋ͬͨΒ͍͠

    View Slide

  17. py.test
    def inc(x):
    return x + 1
    def test_answer():
    assert inc(3) == 5
    def test_misc():
    assert [1,2,3,4], [1,2,3,4]
    assert isinstance('hello', str)

    View Slide

  18. pytest ͷ࣮ߦ݁Ռ
    ================== FAILURES ===================
    _________________ test_answer _________________
    def test_answer():
    > assert inc(3) == 5
    E assert 4 == 5
    E + where 4 = inc(3)
    test_pyt.py:5: AssertionError
    ===== 1 failed, 1 passed in 0.06 seconds ======

    View Slide

  19. TestࢧԉϥΠϒϥϦ
    • freezegun = Test::TimeΈ͍ͨͳ΍ͭ
    from freezegun import freeze_time
    import datetime
    def test_time():
    with freeze_time("2020-06-06"):
    assert datetime.datetime.now() == \
    datetime.datetime(2020, 6, 6)

    View Slide

  20. Web։ൃ

    View Slide

  21. WebϑϨʔϜϫʔΫ
    'MBTL "NPOతͳܰྔλΠϓ
    %KBOHP 3BJMTతͳΜͰ΋͍ΓϦονλΠϓ
    1ZSBNJE ద౓ͳ͓΋ͯͳ͠

    View Slide

  22. Flask
    from flask import (Flask, request, redirect)
    web = Flask(__name__)
    @web.route('//edit', methods=['POST'])
    def edit():
    title = request.form['title']
    body = request.form['body']
    entry = create(title, body)
    return redirect('/entry/' + entry.id)

    View Slide

  23. WSGI
    • αʔόͱΞϓϦέʔγϣϯؒͷϓϩτίϧ
    • PSGIͷܑ͓͞Μ
    def app(environ, start_response):
    start_response(
    '200 OK', [('Content-Type', 'text/plain')]
    )
    yield b'Hello World\n’

    View Slide

  24. HTTPαʔό
    • جຊ͸ prefork worker model
    • uWSGI͸thread΋࢖͑ΔͬΆ͍?
    V84(* ࠷ۙྲྀߦΓͰଟػೳ
    (VOJDPSO 3VCZͷΞϨ༝དྷͰγϯϓϧ

    View Slide

  25. σʔλϕʔε
    • DB͝ͱͷϥΠϒϥϦ: e.g. mysqlclient
    • API͸PEP 249Ͱඪ४Խ (DBI+DBD)
    import MySQLdb
    conn = MySQLdb.connect(db='enjoy')
    with conn.cursor() as cursor:
    cursor.execute('SELECT UUID_SHORT() as uuid')
    print(cursor.fetchone().get('uuid'))

    View Slide

  26. ORM
    • DBϥΠϒϥϦΛͦͷ··࢖͏͘Β͍Ͱ΋
    42-"MDIFNZ ਓؾɻΫΤϦϏϧμతͳ࢖͍ํ΋
    %KBOHP03. %KBOHP࢖͏ͳΒ

    View Slide

  27. ബ͍Web Appͷߏ੒Λࢼͯ͠Έͨ
    • hakobe/hakoblog-python
    • ബ͍WebϑϨʔϜϫʔΫ (Flask)
    • ORMͳ͠ (mysqlclientΛ௚ʹ࢖͏)
    • ServiceϨΠϠ
    • ςϯϓϨʔτΤϯδϯ͸ Jinja2

    View Slide

  28. ORM࢖Θͣʹૉ๿ʹ΍͍ͬͯ͘
    class BlogLoader():
    @classmethod
    def find_by_id(cls, db, blog_id):
    with db.cursor() as cursor:
    row = cursor.execute('''
    SELECT id, owner_id, title
    FROM blog
    WHERE id = %s''',
    (blog_id, )
    ).fetchone()
    return Blog(**row)

    View Slide

  29. ϔϧύΛఆ͍͍ٛͯ͠ײ͡ʹςετ
    def test_find_by_id():
    "EntryLoader.find_by_id() can find a entry by id"
    db = DB()
    entry = create_entry()
    found_entry = EntryLoader.find_by_id(db, entry.id)
    assert isinstance(found_entry, Entry)
    assert found_entry.id == entry.id

    View Slide

  30. σʔλղੳ

    View Slide

  31. σʔλղੳϥΠϒϥϦ
    • ͱʹ͔͘ॆ࣮ͯ͠Δ ɹ ͷΩϥʔίϯςϯπ
    • numpy
    • scipy
    • scikit-learn
    • pandas
    • matplotlib
    • Jupyter notebook
    • σʔλղੳ͍ͨ͠ਓ͕ू·͍ͬͯͯ޷॥؀

    View Slide

  32. Numpy
    • ΊͬͪΌߴ଎ʹߦྻԋࢉͰ͖Δ΍ͭ
    • ߦྻ಺ͷσʔλܕΛ౷Ұ͢Δ͜ͱͰC΍
    FortranͰߴ଎ʹԋࢉՄೳʹͯ͠Δ

    View Slide

  33. Numpy
    import numpy as np
    m1 = np.array([
    [1, 2, 3],
    [4, 5, 6],
    ])
    m2 = np.array([
    [ 7, 8, 9],
    [10, 11, 12],
    ])
    m1.dot(m2.T)
    np.zeros([2, 3])
    # array([[ 0., 0., 0.],
    # [ 0., 0., 0.]])
    np.identity(2)
    # array([[ 1., 0.],
    # [ 0., 1.]])
    np.arange(10).reshape(2,5)
    # array([[0, 1, 2, 3, 4],
    # [5, 6, 7, 8, 9]])

    View Slide

  34. Scipy
    • NumpyϕʔεͷศརͳՊֶܭࢉάοζू
    • ౷ܭͱ͔ઢܗ୅਺ͱ͔৴߸ॲཧͱ͔??
    • ౷ܭάοζ͸ABςετͷݕఆͱ͔ʹ࢖͑Δ

    View Slide

  35. Scipy
    • ࢀߟ: A/Bςετʹ༻͍ΒΕΕΔ౷ܭతݕఆ
    ख๏ʢϩδοΫʣͷ·ͱΊˍൺֱ
    import scipy
    import scipy.stats
    data = [
    # click, access
    [ 150, 500120 ], # A
    [ 70, 320050 ], # B
    ]
    chi2, p, dof, expected = scipy.stats.chi2_contingency(data)
    print(p) # 0.0339

    View Slide

  36. scikit-learn
    • σʔλ෼ੳ/σʔλϚΠχϯά ϥΠϒϥϦू
    • ධՁͷͨΊͷศརάοζ΋
    • ͰػցֶशΤϯδχΞͷؾ෼ʹͳΕΔ
    from sklearn import svm
    svc = svm.SVC()
    svc.fit(X, y)
    svc.predict(Xtest)

    View Slide

  37. pandas
    • σʔλղੳϥΠϒϥϦ
    • ϝϞϦ্ͷσʔλʹରͯ͠SQLΈ͍ͨʹ

    σʔλΛϑΟϧλͨ͠Γू໿ͨ͠ΓͰ͖Δ
    • ௐࠪܥͷλεΫͰศར౓͕ߴ͍

    View Slide

  38. matplotlib
    • σϑΝΫτͷάϥϑඳըϥΠϒϥϦ
    • ͍͍ͩͨͳΜͰ΋Ͱ͖ͯศར
    • API͕Ή͍ͣͷͰ୅ସϥΠϒϥϦ͕ຄڵ͍ͯ͠
    Δͱ͔
    • ݕࡧΩʔϫʔυ: “matplotlib alternative”

    View Slide

  39. Jupyter notebook
    • REPLͷ͓Խ͚(ݩIPython)
    • ίʔυΛ࣮ߦͨ͠Γ࣮ߦ݁ՌΛදࣔͨ͠Γ

    આ໌Λॻ͍ͨΓͰ͖ΔWebΞϓϦ
    • ΊͪΌͪ͘Όࢼߦࡨޡ͠΍͍͢
    • ͳΊ͚ͯͨͲ࣮ࡍ͔ͭ͏ͱ͛͢ʔࢼߦࡨޡ͠
    ΍͍͢…

    View Slide

  40. ݴޠͷਐԽ

    View Slide

  41. ܕΞϊςʔγϣϯ
    • ؔ਺΍ม਺ͷܕΛ෦෼తʹهड़Ͱ͖Δ
    • Generics΍Structual subtyping΋
    • ݴޠػೳͱͯ͠͸ΞϊςʔγϣϯͷΈ
    • ͋͘·Ͱ΋ಈతܕ෇͚͕ओ
    • Smart::Argsͷ͍͍΍ͭ͘Β͍

    View Slide

  42. ࣗ࡞filterؔ਺΁ͷܕ෇͚
    from typing import List, Callable, TypeVar
    T = TypeVar('T')
    def even(n: int) -> bool:
    return n % 2 == 0
    def filter(l: List[T], f: Callable[[T], bool]) -> List[T]:
    result: List[T] = []
    for e in l:
    if f(e):
    result.append(e)
    return result
    filter(['a', 'b', 'c'], even)

    View Slide

  43. mypy
    • ܕΞϊςʔγϣϯΛ࢖͏ܕνΣοΧʔ࣮૷
    > mypy filter.py
    filter.py:14: error: Argument 2 to "filter" has
    incompatible type Callable[[int], bool]; expected
    Callable[[str], bool]

    View Slide

  44. typeshed
    • TypeScriptͷDefinitelyTypedΈ͍ͨͳ

    ܕఆٛϦϙδτϦ
    • .pyi ͱ͍͏֦ுࢠͰఆٛΛ͚ͩΛಡΈࠐΉ

    ࢓૊Έ͕͋Δ
    • https://github.com/python/typeshed

    View Slide

  45. asyncio
    • ࠷ۙ࢖͑Δඪ४ϥΠϒϥϦ (Python 3.4 ~
    • ਺͋ΔඇಉظϥΠϒϥϦΛ౷Ұ
    • ཁ͸AnyEvent(Perl೴
    • ೿ੜϥΠϒϥϦ΋ग़͖ͯͯΔ: e.g. aiohttp
    • ߏจʹ૊Έࠐ·Εͨ (Python 3.6 ~

    View Slide

  46. asyncio ͱ async/await ߏจ
    import aiohttp
    import asyncio
    async def fetch(session, url):
    with aiohttp.Timeout(10, loop=session.loop):
    async with session.get(url) as response:
    return await response.text()
    async def main(loop):
    async with aiohttp.ClientSession(loop=loop) as session:
    html = await fetch(session, 'http://python.org')
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main(loop))

    View Slide

  47. ίϛϡχςΟ

    View Slide

  48. ίϛϡχςΟ
    • ࣮͸͋Μ·Γ஌Βͳ͍… ڭ͍͑ͯͩ͘͞ʂ
    • PyCon ͸͍͢͝੝Γ্͕ͬͯ·͢Ͷʂʂ

    View Slide

  49. ࢖ΘΕͯΔ҆৺ײ
    • اۀ
    • fastly/Google/redhat/Microsoft ͳͲ..
    • ࠷৽ٕज़/اۀϥΠϒϥϦ
    • AWS/Google/Swaggerͱ͔..
    • ڭҭ
    • Raspberry Pi

    View Slide

  50. ·ͱΊ

    View Slide

  51. ·ͱΊ
    • PythonงғؾΛͬ͘͟Γ঺հ
    • ݁ہPython͸Ͳ͏ͳΜ?

    ศརͳ৔໘Ͱ͸࢖͍ͬͯͬͨΒ͑͑ΜͪΌ͏
    • ͍ΖΜͳ͜ͱ͕Ͱ͖ΔΑ͏ʹɺPython΋

    ࢖͍͜ͳͤΔͱྑ͍Ͱ͢Ͷʂ

    View Slide