最終更新日:
Python についての簡単な紹介。
環境設定
Visual Studio Codeの場合
データ構造(リスト、辞書、集合、タプル)
データ構造 | 概要 | 表記例 |
---|---|---|
リスト | 一般的な配列に使う | ['a', 'b'] |
辞書 | 連想配列として使う | {'a':1, 'b':2} |
集合 | 重複を許さないリスト。検索が高速。 | {'a', 'b'} |
タプル | 挿入順を保証できるリスト。変更できないリスト。 | ('a', 'b') |
リストはスライスできる。
stepにマイナスを指定すると逆順に参照できる。
startにマイナスを指定すると後ろからの文字数を指定できる。
letters[start:stop:step]
Pythonの辞書はキーと値のペア(kv:key/value pair)。変更可能なハッシュテーブルとして実装されている。
C++とJavaでは辞書は「マップ」と呼ばれる。
PerlとRubyでは辞書は「ハッシュ」と呼ばれる。
person = { '名前': 'Taro Yamada', '性別': '男性', '職業': '研究者'}
辞書を反復処理する
for k, v in sorted(person.items()): print(k, 'の値は', v)
集合は重複を取り除く(キーと値は存在しない。setで集合に変換。unionで集合を結合。differenceは差集合。intersectionは積集合)
u = word1.union(set(word2))
d = word1.difference(set(word2))
i = word1.intersection(set(word2))
注:空の集合はset()と表現される
データを変更しない場合はタプルを使う(要素が1つだけのときは必ず,を後ろにつける。そうしないとタプルにならないので注意。)
t = ('Python', )
辞書の辞書を作ることも可能(pprintモジュールを使うと、整形して表示できる)
import pprint
dict['ja'] = {'表示':'日本語', '英語':'japanese'}
dict['en'] = {'表示':'英語', '英語':'english'}
pprint.pprint(dict)
zip、アンパック、enumerate(要素の値とインデックスの組み合わせ)
#結合 for d in zip(city, sale): print(d) #分解 for c, s in zip(city, sale): print("city:", c, " sales:", s) #要素とインデックスを組み合わせ for d in enumerate(city): print(d)
リストを集計する
max(リスト) 最大値を求める
min(リスト) 最小値を求める
sum(リスト) 合計値を求める
sorted(リスト) ソートする(reverse=Trueとすると逆順ソート)
関数定義
関数直下の"""で囲まれた箇所は説明文。bool関数はTrue/Falseを返す。戻り値は複数の値を返すことも可能。
def search4vowels(word): """入力された単語内の母音を表示する""" vowels = set('aeiou') found = vowels.intersection(set(word)) return bool(found)
Python3からアノーテーションにより引数・戻り値の型を表現できる(オプション)。
word:strは文字列を引数に取る、-> setは戻り値が集合(set)であることを示す。
def search4vowels(word: str) -> set: """指定された単語内の母音を表示する""" return set('aeiou').intersection(set(word))
デフォルト引数を指定できる。
def search4vowels(word: str, letters: str='aeiou') -> set: """入力された単語内の母音を表示する""" return set(letters).intersection(set(word))
呼び出し側でキーワード引数を指定できる。
このとき引数の順序は問題にならない。
serch4vowels(letters='xyz', word='abc')
Pythonはオブジェクト参照渡し
代入文があるとオブジェクトが上書きされる。
代入文がなく、不変なデータでなければ、オブジェクトが変更される。
def double(arg): print('実行前':, arg) arg = arg * 2 #オブジェクト上書き print('実行後:', arg) def change(arg): print('実行前':, arg) arg.append('追加データ') print('実行後:', arg) num = 10 double(num) print(num) # データは更新されていないように見える numbers = [1, 2, 3] change(numbers) print(numbers) # 追加データが見える
lamda関数(無名関数)
data = [1,2,3,4,5] for d in map(lambda x: x*2, data): print(d)
リスト内包表記でも同じ
data = [1,2,3,4,5] for d in map(x*2 for x in data): print(d)
モジュール
関数を持つファイルがモジュールになる。
import ファイル名(拡張子.pyを除く)で参照できる
モジュールは、作業ディレクトリ、site-packages、標準ライブラリ、のいずれかに置く。
Python3.4以降ではsetuptoolsモジュールを使うと簡単に配布パッケージが作成できる
setup.pyとREADME.txt(空でもよい)の2つがあれば良い
py_modulesにはパッケージに入れる.pyファイルのリストを指定する。
from setuptools import setup setup( name='testmodule', version='1.0', description='test module', author='author', author_email='xxx@xxx.com', url='xxx.com', py_modules=['testmodule'] )
配布パッケージの作成(Windows)。
sdistはソース配布ファイルに結合することを指定している。ソースコードを含む。
py -3 setup.py sdist
配布パッケージの作成(Linux)
python3 setup.py sdist
pipによるパッケージのインストール
py -3 -m pip install testmodule-1.0.zip (Windows)
sudo python3 -m pip install testmodule-1.0.tar.gz (Linux)
第3者と共有したい場合、配布パッケージをPyPIというWebベースの集中管理型ソフトウェアリポジトリにアップロードすることができる。
テストツールとPEP8準拠
py -3 -m pip install pytest
py -3 -m pip install pytest-pep8
py.test --pep8 testmodule.py
Webアプリケーション
Flaskのインストール
py -3 -m pip install Flask
サンプルコード(webappフォルダにhello_flask.pyで保存する)
"@app.route('/')"は関数デコレータで関数のコードを変更せずに既存の関数の振る舞いを追加する。
下記の例では、url '/'をhelloにマッピングしている
from flask import Flask app = Flask(__name__) @app.route('/') def hello() -> str: return 'Hello world from Flask!' app.run()
py -3 hello_flask.pyで実行(終了はCtrl+C)
Webページにはテンプレートを使う(jinja2)
base.html
<!doctype html> <html> <head> <title>{{ the_title }}</title> <link rel="stylesheet" href="static/xxx.css" /> <body> {% block body %} {% end body %} </body> </head> </html>
entry.html
{% extends 'base.html' %} {% block body %} <h2>{{ the_title }}</h2> <form method="POST" action='/serach4'> <table> <p>このフォームを使って検索リクエストを送ってください。</p> <tr> <td>フレーズ:</td> <td><input name='phrase' type="text" width='60'></td> </tr> <tr> <td>文字:</td> <td><input name='letters' type="text" value='aeiou'></td> </tr> </table> <p>準備ができたら、以下のボタンを押してください。</p> <p><input value='実行' type="text"></p> </form> {% end body %}
result.html
{% extends 'base.html' %} {% block body %} <h2>{{ the_title }}</h2> <p>以下のデータを送信しました。</p> <table> <p>このフォームを使って検索リクエストを送ってください。</p> <tr> <td>フレーズ:</td> <td>{{ the_phrase }}</td> </tr> <tr> <td>文字:</td> <td>{{ the_letters }}</td> </tr> </table> <p>{{ the_phrase }}から{{ the_letters }}を検索すると、次の結果を返します。</p> <h3>{{ the_results }}</h3> </form> {% end body %}
サンプルコード(テンプレート使用)
@app.routeのデフォルトは"GET"メソッド。
@app.route('/entry', methods=['GET', 'POST']とするとGET,POSTの両方に対応できる。
app.run(debug=True)とすると変更時に自動リロードしてくれる
from flask import Flask, render_template app = Flask(__name__) @app.route('/entry', methods=['POST']) def entry_page() -> str: return render_template('entry.html', the_title='Hello world from Flask!') app.run()
フォルダ構成
webapp -- test.py
webapp -- static --- xxx.css
webapp -- templates --- base.html, entry.html, results.html
リクエストデータの処理(requestパッケージ)
from flask import Flask, render_template, request app = Flask(__name__) @app.route('/search', methods=['POST']) def entry_page() -> str: phrase = request.form['phrase'] letters = request.form['letters'] return str(search(phrase, letters)) app.run()
リクエストデータのリダイレクト(redirectパッケージ)・・・不要
'302'はリダイレクトを示す。
from flask import Flask, render_template, request, redirect app = Flask(__name__) @app.route('/') def hello() -> '302': return redirect('/entry') app.run()
リクエストデータのリダイレクト
@app.routeに複数のURLをマッピングすればよい
from flask import Flask, render_template, request app = Flask(__name__) @app.route('/') @app.route('/entry') def hello() -> str: return hello() app.run()
ローカル実行との区別
__name__と__main__を使う
if __name__ == '__main__': app.run()
ファイル操作
ファイルのオープン、処理、クローズ:
tasks = open('todo.txt') for task in tasks: print(task, end='') tasks.close()
ファイルのオープン、処理、クローズ(with):デフォルトはReadモード。
自動でクローズ処理をしてくれる。
with open('todo.txt') as tasks: for task in tasks: print(task, end='')
ファイルのオープン、処理、クローズ(with):Writeモード。
戻り値が無いことを示すのにNoneを使う
def log_request(req: 'falsk_request', res: str) -> None: with open('vsearch.log', 'a') as log: print(req.form, req.remote_addr, req.user_agent, res, file=log, sep='|')
ファイルのオープン、処理、クローズ(with):ログ表示。
escape関数でHTMLタグをエスケープする(from falsk import escapeが必要)
@app.route('/viewlog') def view_the_log() -> str: with open('vsearch.log') as log: contents = log.read() return escape(contents)
ファイルのオープン、処理、クローズ(with):ログ表示。
splitとappendを使ってlistに登録
@app.route('/viewlog') def view_the_log() -> str: contents = [] with open('vsearch.log') as log: for line in log: contents.append([]) for item in line.split('|'): contents[-1].append(escape(item)) return str(contents)
ファイルのオープン、処理、クローズ(with):ログ表示。HTML形式。
@app.route('/viewlog') def view_the_log() -> str: contents = [] with open('vsearch.log') as log: for line in log: contents.append([]) for item in line.split('|'): contents[-1].append(escape(item)) titles = ('フォームデータ', 'リモートアドレス', 'ユーザエージェント', '結果') return render_template('viewlog.html', the_title='ログの閲覧', the_row_title=titles, the_data=contents,)
HTML形式。tableで表示。viewlog.htmlとして保存。
{% extends 'base.html' %} {% block body %} <h2>{{ the_title }}</h2> <table> <tr> {% for row_title in the_row_titles %} <th>{{row_title}}</th> {% endfor %} </tr> {% for log_row in the_data %} <tr> {% for item in log_row %} <td> {{item}} </td> {% endfor %} </tr> {% endfor %} </table> {% endblock %}
CSVファイル
import csv f = open("Sasmple.csv", "r") rd = csv.reader(f) for row in rd: for col in row: print(col, end=",") print() f.close()
import csv f = open("Sasmple.csv", "w") w = csv.writer(f) w.writerow(["ABC", "DEF"]) w.writerows([["ABC", "DEF"],["GHI", "JKL"]])
JSONファイル
import json f = open("Sasmple.json", "r") data = json.load(f) print(data) f.close()
json.dump({"ABC":10, "DEF":20}, f)
データベース操作
MySQLのインストール
MySQL-Connector/Pythonのインストール
py -3 -m pip install mysql-connector-python
Webアプリケーションのデータベースとテーブルを作成する
mysql> create database vsearchlogDB;
mysql> grant all on vsearchlogDB.* to 'vsearch' identified by 'vsearchpasswd';
mysql> quit
> mysql -u vsearch -p vsearchlogDB
mysql> create table log( -> id int auto_increment primary key, -> ts timestamp default current_timestamp, -> phrase varchar(128) not null, -> letters varchar(32) not null, -> ip varchar(16) not null, -> browser_string varchar(256) not null, -> results varchar(64) not null);
データベースにログ追加
def log_request(req: 'flask_request', res: str) -> None: """Webリクエストの詳細と結果をロギングする。""" dbconfig = { 'host': '127.0.0.1', 'user': 'vsearch', 'password': 'vsearchpasswd', 'database': 'vsearchlogDB', } conn = mysql.connector.connect(**dbconfig) cursor = conn.cursor() _SQL = """insert into log(phrase, letters, ip, browser_string, results) values (%s, %s, %s, %s, %s)""" cursor.execute(_SQL, (req.form['phrase'], req.form['letters'], req.remote_addr, req.user_agent.browser, res, )) conn.commit() cursor.close() conn.close()
クラス
__init__は初期化の特殊メソッド
クラスメソッドの第1引数は必ずselfをつける
class CountFromBy: def __init__(self, v: int=0, i: int=1) -> None: self.val = v self.incr = i def increase(self) -> None: self.val += self.incr def __repr__(self) -> str: return str(self.val)
コンテキストマネジメントプロトコル
__enter__は前処理を行う。
__exit__は後処理を行う。
__init__は初期化を行う。
__init__ -> __enter__ -> __exit__ の順で呼ばれる
データベースクラス
import mysql.connector class UseDatabase: def __init__(self, config: dict) -> None: self.configuration = config def __enter__(self) -> 'cursor': self.conn = mysql.connector.connect(**self.configuration) self.cursor = self.conn.cursor() return self.cursor def __exit__(self, exc_type, exc_value, exc_trace) -> None: self.conn.commit() self.cursor.close() self.conn.close()
クラスを使ったwith構文に置き換える
app.config['dbconfig'] = { 'host': '127.0.0.1', 'user': 'vsearch', 'password': 'vsearchpasswd', 'database': 'vsearchlogDB', } def log_request(req: 'flask_request', res: str) -> None: """Webリクエストの詳細と結果をロギングする。""" with UseDatabase(app.config['dbconfig']) as cursor: _SQL = """insert into log(phrase, letters, ip, browser_string, results) values (%s, %s, %s, %s, %s)""" cursor.execute(_SQL, (req.form['phrase'], req.form['letters'], req.remote_addr, req.user_agent.browser, res, ))
データベースから取得した情報を表示する
@app.route('/viewlog') def view_the_log() -> str: with UseDatabase(app.config['dbconfig']) as cursor: _SQL = """select phrase, letters, ip, browser_string, results from log""" cursor.execute(_SQL) contents = cursor.fetchall() titles = ('フレーズ', 'フォームデータ', 'リモートアドレス', 'ユーザエージェント', '結果') return render_template('viewlog.html', the_title='ログの閲覧', the_row_titles=titles, the_data=contents,)
いくつのリクエストに応答したか
select * from log;
select count(*) from log;
もっとも一般的な検索文字のリストは何か
select count(letters) as 'count', letters from log
group by letters
order by count desc
limit 1;
リクエストがどのIPアドレスから来たか
select distinct ip from log;
最もよく使われているブラウザは何か
select browser_string, count(browser_string) as 'count' from log
group by browser_string
order by count desc
limit 1;
クラス変数
selfのつかない変数はクラスで共通。
クラスメソッド
@classmethodの下に定義する。
clsはクラス名を参照するのに用いる
@classmethod def getCount(cls): return cls.count
親クラスのメソッド呼び出し
super().親クラスのメソッド()という形式で呼び出す。
関数デコレータ
セッション(session)
from flask import Flask, session app = Flask(__name__) app.secret_key = 'YouWillNeverGuess' @app.route('/setuser/') def setuser(user: str) -> str: session['user'] = user return 'User値を設定:' + session['user'] @app.route('/getuser') def getuser() -> str: return 'User値の現在の設定:' + session['user'] if __name__ == '__main__': app.run(debug=True)
可変長の引数
*は「引数のリストを受け取る」という意味。ゼロ個以上の引数。
def myfunc(*args): for a in args: print(a, end=' ') if args: print()
呼び出し時のリスト展開
*を指定すると引数のリストに展開される
values = [1, 2, 3, 5, 7, 11] myfunc(values) myfunc(*values)
任意のキーワード引数を受け取る
**はキーワード引数
def myfunc2(**kwargs): for k, v in kwargs.items(): print(k, v, sep='->', end=' ') if kwargs: print()
デコレータ functoolsのwraps関数
独自のデコレータを作成する場合
from flask import session from functools import wraps def check_logged_in(func): @wraps(func) def wrapper(*args, **kwargs): if 'logged_in' in session: return func(*args, **kwargs): return 'ログインしていません。' return wrapper
デコレータを利用
デコレータをインポートする
@構文でデコレータを使う
from checker import checker_logged_in @app.route('/page1') @checker_logged_in def page1() -> str: return 'これはページ1です。'
デコレータを作成するためのコードテンプレート
from functools import wraps def decorator_name(func): @wraps(func) def wrapper(*args, **kwargs): # 1. デコレートされる関数を呼び出す前に実行するコードを各。 # 2. 必要に応じてデコレートされる関数を呼び出し、必要なら結果を返す。 return func(*args, **kwargs) # 3. デコレートされる関数を呼び出す代わりに実行するコードを書く。 return wrapper
例外処理
try-except
try: with open('myfile.txt') as fh: file_data = fh.read() print(file_data) except FileNotFoundError: print('データファイルがありません。') except PermissionError: print('許可されていません。') except Exception as err: print('他のエラーが発生しました。', str(err)) #err = sys.exc_info() #for e in err: # print(e) else: #例外が起きなかったときに処理する文 ... finally: #必ず最後に処理する文 ...
カスタム例外を作成する
from DBcm import UseDatabase, ConnectionError, CredentialsError class ConnectionError(Exception): pass raise ConnectionError('接続できません。') try: raise ConnectionError('エラー') except ConnectionError as err: print('データベース接続エラー:', str(err)) except CredentialsError as err: print('ユーザーID/パスワード エラー:', str(err)) except Exception as err: print('その他のエラー:', str(err)) return 'Error'
SQLErrorを投げる
class SQLError(Exception): pass class UseDatabase: def __enter__(self) -> 'cursor': try: ... self.conn.close() if exc_type is mysql.connector.errors.ProgrammingError: raise SQLError(exc_value) elif exc_type: raise exc_type(exc_value) def __exit__(self, exc_type, exc_value, exc_traceback): self.conn.commit() self.cursor.close() self.conn.close() if exc_type is mysql.connector.errors.ProgrammingError: raise SQLError(exc_value)
スレッド
from threading import thread try: t = Thread(target=execute_slowly, args=(glacial, plodding, leaden)) t.start() except Exception as err: print('**** ロギングが失敗しました:', str(err))
イタレーション
from datetime import datetime import pprint def convert2ampm(time24: str) -> str: return datetime.strptime(time24, '%H:%M').strftime('%I:%M%p') with open('buzzers.csv') as data: ignore = data.readline() flights = {} for line in data: k, v = line.strip().split(',') flights[k] = v pprint.pprint(flights) print() flights2 = {} for k, v in flights.items(): flights2[convert2ampm(k)] = v.title() pprint.pprint(flights2)
内包表記のパターン
内包表記の方がforループより高速
destinations = [] for dest in flights.values() destinations.append(dest.title()) ---> more_dests = [dest.title() for dest in flights.values()]
リスト内包表記
data = [1,2,3,4,5] ndata = [n*2 for n in data if n!= 3]
ジェネレータ
()で囲まれた内包表記のように見えるもの
データ生成の度に呼ばれるので待ち時間がない
for i in (x*3 for x in [1,2,3,4,5]): print(i)
ジェネレータ(yeild)
returnで終了せずに、待機して復帰する
import requests def gen_from_urls(urls: tuple) -> tuple: for resp in (requests.get(url) for url in urls): yeild len(resp.content), resp.status_code, resp.url
正規表現
import re ptr = "\.(csv|html|py)$" str = ["Sample.csv", "Sample.exe", "test.py", "index.html"] pattern = re.compile(ptr) for valuestr in str: res = pattern.search(valuestr) if res is not None: print("found") else: print("not found") for valuestr in str: res = pattern.sub(".txt", valuestr) mst = "変換前:" + valuestr + " 変換後:" + res print(msg)
Webスクレイピング
モジュール | 概要 |
---|---|
webbrowser | Python付属のモジュール。指定したページをブラウザで開く。 |
Requests | インターネットからファイルやWebページをダウンロードする。 |
Beautiful Soup | HTMLをパースする |
Selenium | Webブラウザを起動し制御する。ブラウザ上のフォームを記入したり、マウスクリックをシミュレートできる。 |
webbrowserの例(Google Mapで地図を表示する)
(引数で住所を指定するか、メモ帳などに記載した内容をCtrl+Cでコピーした状態で引数なしで起動する)
py -3 -m pip install pyperclipでpyperclipをインストールする必要あり。
import webbrowser, sys, pyperclip if len(sys.argv) > 1: address = ' '.join(sys.argv[1:]) else: address = pyperclip.paste() webbrowser.open('https://www.google.co.jp/maps/place/' + address)
requestsの例
py -3 -m pip install requestsでモジュールをインストール
ファイル名はrequests.py以外にすること
import requests res = requests.get('http://automatetheboringstuff.com/files/rj.txt') print(type(res)) res.raise_for_status() if (res.status_code == requests.codes.ok): print(len(res.text)) print(res.text[:250]) play_file = open('RomeoAndJuliet.txt', 'wb') for chunk in res.iter_content(100000): play_file.write(chunk) play_file.close() print('exit')
BeautifulSoupの例
pip install beautifulsoup4でモジュールをインストール
import requests, bs4 res = requests.get('http://suoyimi.blog.jp/') res.raise_for_status() bs4res = bs4.BeautifulSoup(res.text, features="html.parser") elems = bs4res.select('p') print(type(elems)) print(len(elems)) length = len(elems) for elem in elems: print(elem.attrs) print(elem.getText())
Google検索結果の上位5ページを開く例
import requests, sys, webbrowser, bs4 print('Googling...') url = 'http://www.google.com/search?q=' + ''.join(sys.argv[1:]) print(url) res = requests.get(url) res.raise_for_status() html_file = open('example.html', 'w', encoding='utf-8') html_file.write(res.text) html_file.close() soup = bs4.BeautifulSoup(res.text, features="html.parser") link_elems = soup.select('.kCrYT a') print(link_elems) print(len(link_elems)) num_open = min(5, len(link_elems)) print(num_open) for i in range(num_open): webbrowser.open('http://www.google.com' + link_elems[i].get('href'))
コミック画像のダウンロードの例
import requests, os, bs4 url = 'http://xkcd.com' os.makedirs('xkcd', exist_ok=True) while not url.endswith('#'): # ページをダウンロードする print('ページをダウンロード中 {}...'.format(url)) res = requests.get(url) res.raise_for_status() soup = bs4.BeautifulSoup(res.text) # コミック画像のURLを見つける comic_elem = soup.select('#comic img') if comic_elem == []: print('コミック画像が見つかりませんでした。') else: comic_url = 'http:' + comic_elem[0].get('src') # 画像をダウンロードする print('画像をダウンロード中 {}...'.format(comic_url)) res = requests.get(comic_url) res.raise_for_status() # 画像を./xkcdに保存する image_file = open(os.path.join('xkcd', os.path.basename(comic_url)), 'wb') for chunk in res.iter_content(100000): image_file.write(chunk) image_file.close() # PrevボタンのURLを取得する prev_link = soup.select('a[rel="prev"]')[0] url = 'http://xkcd.com' + prev_link.get('href') print('完了')
Seleniumでブラウザ制御の例
pip install seleniumでモジュールをインストール
chromedriver.exeをダウンロードしてパスの通った場所に置く
https://chromedriver.chromium.org/downloads
from selenium import webdriver from selenium.webdriver.common.keys import Keys browser = webdriver.Chrome() print(type(browser)) browser.get('http://inventwithpython.com') link_elem = browser.find_element_by_link_text('Read Online for Free') print(type(link_elem)) link_elem.click() html_elem = browser.find_element_by_tag_name('html') html_elem.send_keys(Keys.END) browser.refresh() browser.back()
pyinstallerでseleniumをchromedriverと一緒にパッケージ化する場合は、以下のようにコマンドを実行する
add-binaryは"コピー元;コピー先"となっている。
pyinstaller ./main.py --onefile --noconsole --add-binary "./driver/chromedriver.exe;./driver"
pythonスクリプトのパス指定も以下のように行う。
sys._MEIPASSにはexeファイルからの実行時に一時フォルダのパスが入る。
def resource_path(relative_path): try: base_path = sys._MEIPASS except Exception: base_path = os.path.dirname(__file__) return os.path.join(base_path, relative_path) driver = webdriver.Chrome(resource_path('./driver/chromedriver.exe'),options=options)
フォームを記入して送信する
from selenium import webdriver login_username = 'username' login_passwd = 'password' browser = webdriver.Chrome() browser.get('http://localhost/redmine/login') email_elem = browser.find_element_by_id(login_username) email_elem.send_keys('not_my_real_email') password_elem = browser.find_element_by_id(login_passwd) password_elem.send_keys('12345') password_elem.submit()
proxy設定
> set HTTP_PROXY=http://{プロキシーサーバ} > set HTTPS_PROXY=http://{プロキシーサーバ} > pip install pyinstaller --proxy=http://{プロキシーサーバ}
実行ファイルの作成
main.pyがスクリプト名。 openpyxlなどを使用する場合、main.pyにしないとエラーになる可能性がある。 Testが出力実行ファイル名。
pip install pyinstaller pyinstaller main.py --onefile --noconsole -n Test
仮想環境
プロジェクト毎に環境を設定する。 pyinstallerで実行ファイルサイズを小さくする目的で用いる。
pip install pipenv cd exe(フォルダ名) pipenv --python 3.9 pipenv shell pipenv install 必要ライブラリ
パッケージインストーラ(pip)
パッケージインストーラ。 ”pip install” と “python -m pip install”で動作が異なる場合があることに注意。 python -m pipとした場合は実行ファイルpythonに対してパッケージをインストールする。 python -m pipを使った方が無難。
参考:https://daeudaeu.com/python-pip-difference/
参考資料
- Head First Python 第2版
- やさしいPython
- 退屈なことはPythonにやらせよう(http://automatetheboringstuff.com/)