Memo/Python

http://dexlab.net/pukiwiki/index.php?Memo/Python
 

'Memo/Python/' には、下位層のページがありません。

Python


例外発生時にstack traceの表示

  • python 2.7.11
  • exception.py
    1. try:
    2.     f = open('sample.txt', 'r')
    3. except Exception, e:
    4.     import traceback
    5.     traceback.print_exc()
  • 実行結果
    1. ./exception.py
    2.  
    3. Traceback (most recent call last):
    4.   File "./exception.py", line 13, in <module>
    5.     f = open('sample.txt', 'r')
    6. IOError: [Errno 2] No such file or directory: 'sample.txt'

InsecurePlatformWarning?の抑制

  • 環境: python 2.7.11 / requests (2.17.3) / urllib3 (1.21.1)
    1. import requests
    2. import requests.packages.urllib3
    3. requests.packages.urllib3.disable_warnings()

python3


yamlの読み書き

  • dictをlistに変換するサンプル: fileexample-yaml.zip
    1. cat example.yml
    2. dict1:
    3.   foo:
    4.     email: foo@example.com
    5.   bar:
    6.     email: bar@example.com
    7.  
    8. ./example-yaml.py < example.yml
    9. - email: foo@example.com
    10.   name: foo
    11. - email: bar@example.com
    12.   name: bar

pipでミラーを指定する

  • コマンド単位で指定
    1. sudo pip install requests==2.5.3 --index-url http://pypi.example.com/simple/ --trusted-host pypi.example.com
  • ユーザ単位で指定
    1. mkdir ~/.pip
    2. vi ~/.pip/pip.conf
    3. ----
    4. [global]
    5. index-url = http://pypi.example.com/simple/
    6.  
    7. [install]
    8. trusted-host = pypi.example.com
    9. ----
  • ホスト単位で指定: /etc/pip.conf

pudb: CUIだけどグラフィカルなデバッガ

pythonデフォルトのデバッガはpdbだが、前後のソースコードが表示されないため、分かりにくい。
pudbはMain, Variables, Stack, Breakpoints画面に分割されるため操作しやすい。

  • インストール
    1. sudo pip install pudb
  • 起動
    1. pudb example.py
コマンド説明
?ヘルプ
q終了
nステップオーバー
sステップイン
rリターン
bブレークポイント

pdb: 標準デバッガ


httplib2でエラーが出た場合

  • ソースからインストールしたpython2.7で以下のようなエラーが出た
    1.   File "/usr/local/lib/python2.7/httplib.py", line 924, in putheader
    2.     str = '%s: %s' % (header, '\r\n\t'.join(values))
    3. TypeError: sequence item 0: expected string, int found
  • httplib2を更新
    1. wget http://httplib2.googlecode.com/files/httplib2-0.8.zip
    2. unzip httplib2-0.8.zip
    3. cd httplib2-0.8/
    4. sudo python setup.py install

CentOS5.xにpython2.6をインストール

  • CentOS5.xはデフォルトでpython2.4がインストールされており、削除できない
  • epelにpython26がある
    1. # EPELリポジトリを追加
    2. sudo rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL
    3. sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/$(uname -i)/epel-release-5-4.noarch.rpm
    4.  
    5. # python 2.6をインストール(awsを使うなら python26-boto も追加)
    6. sudo yum install python26 python26-devel python26-distribute --enablerepo=epel
    7.  
    8. # pipをインストール
    9. sudo easy_install-2.6 pip
    10.  
    11. sudo pip2.6 list                                                                                                                                      
    12. distribute (0.6.10)
    13. pip (1.5.6)
    14. setuptools (0.6c11)
    15. wsgiref (0.1.2)

autopep8: ソースコードを自動でPEP8形式に整形


easy_install でインストールしたパッケージの削除

  • eggのパスを確認して削除すれば良いようだ
    1. sudo easy_install -mxN pip
    2. sudo rm -rf /usr/lib/python2.4/site-packages/pip-1.5.6-py2.4.egg
    3. sudo rm -f /usr/bin/pip

モジュール一覧の取得

  1. python -c "help('modules')"

var_dump: PHP風オブジェクトダンプ

pprint()では文字列、数値、リストといった特定のオブジェクトしかダンプしてくれない。
PHPのvar_dumpはクラス内部の変数もダンプしてくれて便利だったので、似たようなものがあった。

  • インストール
    1. sudo pip install var_dump
  • サンプル
    1. vim test.py
    2. ----
    3. # -*- coding:utf-8 -*-
    4. import sys
    5. from pprint import pprint
    6. from var_dump import var_dump
    7.  
    8. class node(object):
    9.     def __init__(self, name, contents=[]):
    10.         self.name = name
    11.         self.contents = contents[:]
    12.  
    13. x = [node("node-1")]
    14.  
    15. print("pprint: ")
    16. pprint(x)
    17. print("var_dump: ")
    18. var_dump(x)
    19. ----
    20.  
    21. python test.py
    22.  
    23. pprint:
    24. [<__main__.node object at 0x7f15f9723850>]
    25. var_dump:
    26. [{'__type__': '<node #0x7f15f9723850>', 'contents': [], 'name': 'node-1'}]

pip: パッケージ管理

  • pip自体のインストール(epelリポジトリ)
    • CentOS 6.3
      1. yum install python-setuptools python-pip
  • pipを使ってパッケージのインストール
    1. pip install pytz
    2. # バージョンを指定してインストール
    3. pip install pytz==2013.7
  • アップグレード
    1. pip install --upgrade pytz
  • インストール済みパッケージをファイルに出力。中身はテキストファイルなので編集可能。
    1. pip freeze > packages.txt
  • freezeしたパッケージをインストール
    1. pip install -r packages.txt

virtualenv: 実行環境を仮想的に提供する

  • CentOS6.xではpython2.6系がデフォルトで入っており、yum等で使っているため直接バージョンアップ等はできない。
  • virtualenv で作業環境を複数作る事ができる。pip install等はそれぞれの環境で行う事になる
  • python自体のインストールは別で行い、作業環境を作成する時にpythonのパスを指定(-p PYTHON_EXE)する
  1. python -V
  2. Python 2.6.6
  3.  
  4. sudo yum install python-devel python-setuptools python-tools python-pip
  5. sudo pip install virtualenv virtualenvwrapper
  6. vim ~/.bashrc
  7. ----
  8. if [ -f /usr/bin/virtualenvwrapper.sh ]; then
  9.     export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python
  10.     export WORKON_HOME=$HOME/.virtualenvs
  11.     source /usr/bin/virtualenvwrapper.sh
  12. fi
  13. ----
  14. source ~/.bashrc
  15.  
  16. # pipインストール時に"bz2 module is not available"エラーが出るため
  17. sudo yum install bzip2-devel
  18.  
  19. # python 2.7.6をインストールする場合(3.3.4も同様)
  20. wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tgz
  21. tar xvfz Python-2.7.6.tgz
  22. cd Python-2.7.6
  23. ./configure --prefix=/usr/local --with-bz2
  24. make
  25. sudo make altinstall
  26.  
  27. # 仮想環境作成
  28. mkvirtualenv -p /usr/local/bin/python2.7 py27
  29. ...
  30. python -V
  31. Python 2.7.6
  32. # install等、自由に作業
  33.  
  34. # 無効化
  35. deactivate
  36.  
  37. # 有効化(オプション無しで環境一覧)
  38. workon py27
  39.  
  40. # 環境削除
  41. rmvirtualenv py27

CentOS6.xにpython2.7をインストール

  • CentOSがpython2.6系を必須にしており、アンインストール等はできない
  • epelにpython27がある
  1. yum install python27 python27-devel python27-tools python27-distribute
  2. easy_install-2.7 pip
  3.  
  4. which python2.7 pip
  5. /usr/bin/python2.7
  6. /usr/bin/pip

WOL(Wake on LAN)

  • http://ja.wikipedia.org/wiki/Wake-on-LAN
  • BIOSでWOLが有効な場合にマジックパケットを送信して電源ONにする
    1. import socket
    2. import binascii
    3.  
    4. def wol(macs, ip='<broadcast>', port=9):
    5.     """
    6.     wake on lan
    7.     """
    8.     macs = macs.split(',')
    9.  
    10.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    11.     s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    12.     for mac in macs:
    13.         for sep in ':-':
    14.             if sep in mac:
    15.                 mac = ''.join([x.rjust(2, '0') for x in mac.split(sep)])
    16.                 break
    17.         mac = mac.rjust(12, '0')
    18.         p = '\xff' * 6 + binascii.unhexlify(mac) * 16
    19.         s.sendto(p, (ip, port))
    20.     s.close()
    21.  
    22. wol(macs='11-22-33-44-55-66,77-88-99-AA-BB-CC') # 文字列
    23. wol(macs=['11-22-33-44-55-66','77-88-99-AA-BB-CC']) # 配列

isinstance : 変数の型を調べる

  1. print isinstance("test", str) # True
  2. print isinstance(10, int) # True

ping

  • pingモジュールを扱う場合。rootユーザでの実行または、setuidが必要
    1. sudo pip install ping
    2. vim ping.py
    3. ----
    4. import ping
    5.  
    6. print ping.verbose_ping("localhost")
    7. ----
    8.  
    9. sudo python ping.py
    10.  
    11. ping localhost with ... get ping in 0.0730ms
    12. ping localhost with ... get ping in 0.0420ms
    13. ping localhost with ... get ping in 0.0379ms
    14. ping localhost with ... get ping in 0.0379ms

簡易ポートオープンチェック

  • socketを使う
    1. import socket
    2.  
    3. def is_port_open(ip, port):
    4.     try:
    5.         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,0)
    6.         s.settimeout(1)
    7.         s.connect((ip, int(port)))
    8.         s.close()
    9.         return True
    10.     except Exception, e:
    11.         return False
    12.  
    13. print is_port_open('localhost', 22)
    14. # True

三項演算子

分岐して代入処理が1行で書ける

  • 通常
    1. if 10 % 2 == 0:
    2.     var1 = 'even'
    3. else:
    4.     var1 = 'odd'
    5. print var1 # even
  • 三項演算子
    1. var1 = 'even' if 10 % 2 == 0 else 'odd'
    2. print var1 # even

slappasswd互換の{SSHA}, {SHA}形式の生成

  1. # -*- coding: utf8 -*-
  2. import os
  3. import hashlib
  4. import base64
  5.  
  6. def slappasswd(password, password_scheme, salt=os.urandom(4)):
  7.     hash = False
  8.     if password_scheme == "{SSHA}":
  9.         ctx = hashlib.sha1()
  10.         ctx.update( password )
  11.         ctx.update( salt )
  12.         hash = "{SSHA}" + base64.b64encode( ctx.digest() + salt )
  13.     elif password_scheme == "{SHA}":
  14.         ctx = hashlib.sha1()
  15.         ctx.update( password )
  16.         hash = "{SHA}" + base64.b64encode( ctx.digest() )
  17.     return hash
  18.  
  19. print slappasswd('secret', '{SSHA}') # {SSHA}QYkKRfdg3uEIajHpiyYXxUJSBqaZTRod
  20. print slappasswd('secret', '{SHA}')  # {SHA}5en6G6MezRroT3XKqkdPOmY/BfQ=

ヒアドキュメント中で変数参照

  • '{}'そのものを表示したい場合、'{{}}'と入力
    1. var1="foo"
    2. var2="bar"
    3. str=r"""var1={var1}
    4. var2={var2}
    5. {{str}}""".format(**vars())
    6. print str
  • 実行結果
    1. var1=foo
    2. var2=bar
    3. {str}

複数階層のディレクトリ削除

  • shutil.rmtree()
    1. import tempfile
    2. import shutil
    3.  
    4. temp_dir=tempfile.mkdtemp()
    5. print("temp_dir: %s" % temp_dir) # temp_dir: /tmp/tmpMCBIX7
    6. shutil.rmtree(temp_dir)

re: 正規表現

  • 複数行の文字列から、1行ずつマッチ
    1. # -*- coding: utf8 -*-
    2. import re
    3.  
    4. s = """\
    5. 200 /test.html
    6. 404 /foo/bar.html
    7. 200 /404.html"""
    8. print re.findall(r'^404 (.+)', s, re.MULTILINE)
    9. # ['/foo/bar.html']
  • 複数行の文字列から、1行ずつ置換。re.sub(r'...', '', s, re.MULTILINE)ではうまく動作しなかった
    1. # -*- coding: utf8 -*-
    2. import re
    3.  
    4. s = """\
    5. 200 /test.html
    6. 404 /foo/bar.html
    7. 200 /404.html"""
    8. print re.compile(r'^404.+[\r\n]+', re.MULTILINE).sub('', s)
    9. # 200 /test.html
    10. # 200 /404.html

tempfile: 一時ファイル/ディレクトリ

  • python 2.7
    1. # -*- coding: utf8 -*-
    2. import tempfile
    3.  
    4. if __name__ == '__main__':
    5.     fp=tempfile.NamedTemporaryFile(delete=True)
    6.     print("%s" % (fp.name)) # /tmp/tmpEOKEJF
    7.     fp.write("Hello World!")
    8.     fp.close()
    9.  
    10. # vim: ts=4 sw=4 expandtab
  • 一時ディレクトリの作成
    1. # -*- coding: utf8 -*-
    2. import tempfile
    3. import shutil
    4.  
    5. temp_dir=tempfile.mkdtemp()
    6. print("temp_dir: %s" % temp_dir) # temp_dir: /tmp/tmpMCBIX7
    7. shutil.rmtree(temp_dir)
    8.  
    9. # vim: ts=4 sw=4 expandtab

ヒアドキュメントの行頭スペースを削除

  • textwrap.dedent()を使う場合
    1. # -*- coding: utf8 -*-
    2. import textwrap
    3. -
    4. if __name__ == '__main__':
    5.     print '''\
    6. default
    7. message'''
    8.     print '''\
    9.         indent
    10.         message'''
    11.     print textwrap.dedent('''\
    12.         textwrap.dedent
    13.         message''')
    14. # vim: ts=4 sw=4 expandtab
  • 実行
    1. python test.py
    2.  
    3. default
    4. message
    5.         indent
    6.         message
    7. textwrap.dedent
    8. message

日付/時刻/タイムゾーン

  • 日付期間
    1. # -*- coding: utf8 -*-
    2. # sudo pip install python-dateutil
    3.  
    4. from datetime import datetime, timedelta
    5. from dateutil.relativedelta import relativedelta
    6.  
    7. start_date = datetime.strptime('20130930', '%Y%m%d')
    8. end_date = datetime.strptime('20131002', '%Y%m%d')
    9.  
    10. # date span
    11. for dt in range((end_date - start_date).days + 1):
    12.     print start_date + timedelta(dt)
    13. # 2013-09-30 00:00:00
    14. # 2013-10-01 00:00:00
    15. # 2013-10-02 00:00:00
    16.  
    17. # month span
    18. print start_date
    19. while(start_date.year != end_date.year or
    20.       start_date.month != end_date.month):
    21.     start_date = start_date + relativedelta(months=1)
    22.     print start_date
    23. # 2013-09-30 00:00:00
    24. # 2013-10-30 00:00:00
  • 例:タイムゾーン
    1. from datetime import datetime, tzinfo
    2. import pytz
    3.  
    4. # デフォルトはtimezoneが無い
    5. print datetime.now().strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 16:37:01
    6.  
    7. # UTC
    8. print datetime.now(pytz.timezone('UTC')).strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 07:37:53 UTC
    9.  
    10. # GMT
    11. print datetime.now(pytz.timezone('GMT')).strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 07:37:53 GMT
    12.  
    13. # JST
    14. print datetime.now(pytz.timezone('Asia/Tokyo')).strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 16:38:30 JST
    15.  
    16. # UTCからJSTへ変換
    17. date_utc=datetime.now(pytz.timezone('UTC'))
    18. print date_utc.strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 08:01:06 UTC
    19. print date_utc.replace(tzinfo=pytz.timezone('UTC')).astimezone(pytz.timezone('Asia/Tokyo')).strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 17:01:06 JST
    20.  
    21. # 日付文字列からdatetimeへ変換
    22. date_str="22/Oct/2013:17:19:41 +0900"
    23. date_jst=datetime.strptime(date_str, '%d/%b/%Y:%H:%M:%S +0900') # %zが使えなかった(Python 2.6.6, 2.7)
    24. print date_jst.strftime('%Y-%m-%d %H:%M:%S %Z') # 2013-10-22 17:19:41

sys.argv : コマンドライン引数

  • ソース
    1. import sys
    2. from pprint import pprint
    3.  
    4. argv=sys.argv
    5. argc=len(sys.argv)
    6. pprint(argc)
    7. pprint(argv)
  • 実行結果
    1. python test.py foo bar
    2. 3
    3. ['test.py', 'foo', 'bar']

logging


特殊変数

  • __name__
    • スクリプトとして実行された場合は '__main__'
    • moduleとして呼び出された場合は 'モジュール名'

ソースコードにUTF-8を使う

  • 行頭付近に以下を追加
    1. # -*- coding: utf-8 -*-

has_key : 辞書側でキーを持っているかを調べる

  1. d = {'hoge': 100, 'foo':200, 'bar':300}
  2. if d.has_key('hoge'):
  3.     print 'hoge found!'

hasattr : 属性があるかどうかを調べる

  • env.hoge が存在するかどうかをチェック。チェックせずに属性にアクセスすると AttributeError? が発生
    1. if hasattr('env', 'hoge'):
    2.     print(env.hoge)

チートシート

BASIC認証ページを取得

urllib.FancyURLopenerをオーバーライドしてID/PASSを返してやれば良い。

  1.  import urllib
  2.  
  3.  class MyURLopener(urllib.FancyURLopener):
  4.   def prompt_user_passwd(self, host, realm):
  5.   if host == 'ホスト名':
  6.   return ('ID', 'Password')
  7.  
  8.  def execute(hdf, args, env):
  9.   opener = MyURLopener({})
  10.   f = opener.open('https://svn.example.com/projects/ppc/wiki/FctlPpc/mysql')
  11.   print f.read()
  12.   f.close()
  13.  
  14.  execute(1,2,3)

pyスクリプトをexe形式に変換

  • py2exe
    Pythonインストールしなくても実行可能になる。(ランタイムDLLのインストールは必要)

添付ファイル: fileexample-yaml.zip 220件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-06-10 (土) 00:43:32 (408d)