2019年6月に投稿した記事

【Python】動的型付け(Dynamic Typing)

こんにちは!

今回はPythonの特徴の一つである型宣言についてまとめます。

私はもともとJavaを学んでいたので、これはかなり不思議でした。

どうやってPythonは型情報を保持しているのだろうか?

今回はそれについて分かりやすくしたいとおもいます!

そのためには・・・

Pythonの変数の仕組みについても触れていきます!

それではいってみましょう!

目次

  1. Pythonは型宣言がない
  2. 変数の役割
  3. オブジェクトの役割
  4. 変数作成の流れ

Pythonは型宣言がない

Pythonには型宣言がないのは、もはやご存じの通りだと思います。

型宣言というのは、例えばCやJavaでこの変数xをint型で使いますよって変数を使う前に宣言することになります。

Pythonでは型宣言はしません。なぜなら変数を代入するときに型情報もはいっているのです。

ですから、プログラムの実行時に型が自動的に決まります。

そこから動的型付け(Dynamic Typing)と呼ばれています。

じゃあ、どうやって型が決まるのか?気になりますよね。

そこには変数とオブジェクトの役割が非常に重要になってきます。

変数の役割

変数はオブジェクトへのリファレンスのみを保持しています。

プログラムのオブジェクトはコンピュータのメモリに格納されています。リファレンスはオブジェクトの格納されているメモリの場所を指示しているのです。

ざっくりいえば、変数はただオブジェクトがどこに入っているかの情報があります。

C言語をやっている人であればポインターに近いイメージです。ですがPythonのリファレンスはそれよりも扱いやすくなっています。

オブジェクトの役割

実はオブジェクト自身が型情報を持っています

例えば、整数100の値をいれるとその値と同時に自分が整数であるという識別子をもつのです。

それはオブジェクトがヘッダー領域を持つから実現できています。

そしてオブジェクトには2つのヘッダー領域があります。型情報とリファレンスカウンターです。

リファレンスカウンターについてはガベージコレクションと関りが深いので、その時に話します。簡単にいうなら、リファレンスカウンターはいつこの変数はメモリ上から消えるのかを管理しているのです。

変数作成の流れ

変数とオブジェクトの役割が分かれば後は簡単です。変数の代入というのは、変数とオブジェクトをリンクさせることに他なりません。

また変数の作成は値が代入されることでしか作られません。Pythonでは予め変数を作っておくことができないのです。

ですからざっくりと変数がどのように作られるかというと・・・

  1. オブジェクトを作成
  2. 変数作成
  3. 変数がオブジェクトへのリファレンスをもつ

このように変数が格納されます。

実行時に、変数がもつオブジェクトのリファレンスをたどることで、変数とオブジェクトの対応関係が分かります。

まとめ

いかがだったでしょうか?

今回の重要な要点は以下の2つです。

  • 変数はオブジェクトへのリンクを持つのみ
  • オブジェクトは値のほかにも型情報をもつ

また、Pythonの変数は代入でしか作られないことも重要です。defによる関数、import文,class文でさえ代入処理なのです。

これはそれぞれの記事で説明していきたいと思います。

以上になります。

みなさんのPythonライフがより良くなるように祈っています!

【PowerShell】エイリアスをWindows起動時に有効化

こんにちは

今回も備忘録です。

WindowsにもLinuxでいうところのProfileファイルがあるようです。

いちいちエイリアスを設定するのはめんどくさいので最初から使えるようにします。

プロファイルを作っておく

初めて設定する場合は以下のようにprofileファイルを作成します。


New-item –type file –force $profile 

作成したら、notepadで編集します。

 notepad $profile 

これで起動時に実行しておきたいコマンドを書いておけばオッケー

再起動後のエラー

はい、だめでした。以下のようなエラーがでます。

powershell_security_error
セキュリティエラー

要するにスクリプトを実行する権限がないのでできないとのことです。

そうと分かれば、後は権限を書き換えればいいだけの話です!

権限の変更

まず今の権限を確認します。

Get-ExecutionPolicy
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

ただし、これはセキュリティの兼ね合いがあることに気を付けてください。

profileを再読み込み

あとはきちんと読込めるか確認しましょう!

以下で確認できます。


. $profile

これで再起動時でもいつでもあなただけの環境が構築されます。

まとめ

今回はエイリアスの設定がめんどくさかったのでその設定を行いました。

これは他のことにも応用できます。ログインしたら必ず行いたいことをこの$profileに書いておけばいいのです!

以上です。ありがとうございました。

【PowerShell】エイリアスの設定

こんにちは!

Pythonのバージョン毎にインストールした後の起動がめんどくさすぎたことがきっかけでPowerShellを触りました。

Linuxと違ってめんどくさいのでメモ程度に書いておきます。

それではみていきましょう。

エイリアスの一覧を取得する

とりあえず、今あるエイリアスを確認できます。


Get-Alias

エイリアスを設定する

エイリアスを設定します。


Set-Alias  

私はこれでPython3.7のエイリアスを作成しました。


Set-Alias python37 "C:\Users\XXXXX\AppData\Local\Programs\Python\Python37-32\python.exe"

こんな感じですね

エイリアスを確認する

本当に入ったのかどうかを確認します。

変更前後の検証大事!


Get-Alias | Out-String -Stream | Select-String 


Get-Alias | Out-String -Stream| Select-String python37

Alias           python37 > python.exe

これでコマンドが使えます!

エイリアスを削除する

間違ってしまったときにエイリアスを削除することも必要です。


remove-item  alias:

私は一回間違えてコマンドを入力したのでこれを使用しました。


remove-item alias:python37

まぁ参考までにしてください!

まとめ

あまり、Windowsの設定をいじったことがなかったのでいい機会になりました。

時間があるときにまたまとめたいと思います。

以上になります!

【Python】基数変換をしよう

今回は10進数や8進数、16進数の基数変換を自由に行えるような関数を紹介します。

関数 説明
oct8進数へ変換
hex16進数へ変換
int10進数へ変換

8進数に変換

oct関数を使うことで変換可能です。

10進数や16進数、8進数自身から変換ができます。


>>> oct(1_000)
'0o1750'
>>> oct(0o1_000)
'0o1000'
>>> oct(0x1_000)
'0o10000'

16進数に変換

hex関数を使うことで変換が可能です。


>>> hex(1_000)
'0x3e8'
>>> hex(0o1_000)
'0x200'
>>> hex(0x1_000)
'0x1000'

10進数に変換

int関数を使うことで変換が可能です。


>>> int(1000)
1000
>>> int(0o1000)
512
>>> int(0x1000)
4096

Tips・注意点

さて、ほかにも基数の変換ができる方法があるので、それらも紹介します。

int の引数が文字列の場合、基数を指定して変換する

文字列の場合、デフォルトで10進数に変換いたします。

それ以外に変換する場合は基数を指定します。

キーワード引数を使う場合はbaseで指定します。


>>> int('1024')
1024
>>> int('1024',10)
1024
>>> int('0o1024',8)
532
>>> int('0x1024',base=16)
4132

eval関数を用いた10進数への変換

引数が文字列の場合eval関数も使えます。

10進数への変換になりますが。


>>> eval('0o70')
56
>>> eval('100')
100
>>> eval('0o100')
64
>>> eval('0x100')
256

ただし、この方法はコンパイルと実行という手間がかかるため、パフォーマンスが悪いのでやめましょう。

文字フォーマットによる変換


>>> "%o %d %x" % (64, 64, 64)                                                      
'100 64 40'
>>> "%o %d %x" % (0o64, 0o64, 0o64)                                                
'64 52 34'
>>> "%o %d %x" % (0x64, 0x64, 0x64)                                               
'144 100 64'

format関数

さらに、ビルトインクラスのstringにはformat関数があります。

これを用いても変換自体は可能です。


>>> "{0:d} {0:o} {0:x}".format(100)
'100 144 64'
>>> "{0:d} {0:o} {0:x}".format(0o100)
'64 100 40'
>>> "{0:d} {0:o} {0:x}".format(0x100)
'256 400 100'

【補足】位置指定しかできない変更

ほとんどの人はあまり関係ありません。

実はintの関数のキーワード引数としてxがあったので、これを指定することも可能でした。

Python3.6まで


>>> int(x=10)
10

それがPython3.7以降からできなくなっています。

Python3.7から


>>> int(x=1)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'x' is an invalid keyword argument for int()

同じような変更がbool(),float(),list(),tuple()でも行われています。

気を付けてください 笑

まとめ

いかがだったでしょうか?

Tipsのほうが多くなってしまいましたが、おそらく私が知らないだけでまだまだあるかもしれません。

分かり次第また更新しようと思います。

それでは以上になります。

【Python】数値演算の優先順位

今回は、Pythonの数値の演算の優先順位についてまとめたいと思います。

とりあえず、公式サイトからPython3.7時点では以下のようになっています。

下に行くほど優先順位が高いです。

演算 結果
x + yx と y の和
x – yx と y の差
x * yx と y の積
x / yx と y の商
x // yx と y の商の整数部
x % yx / y の剰余
-xx の符号反転
+xx そのまま
abs(x)x の絶対値
int(x)x の整数への変換
float(x)x の浮動小数点数への変換
complex(re, im)実部 re, 虚部 im の複素数。 im の既定値はゼロ。
c.conjugate() 複素数 c の共役複素数
divmod(x, y)(x // y, x % y) からなるペア
pow(x, y)x の y 乗
x ** yx の y 乗

Tips・ 注意点

Pythonでは型の異なる数値型同士の演算を完全にサポートしています。

より複雑な型に合わせて計算してくれます。

つまり、整数型 + 浮動小数点数型なら値として浮動小数点数が返ってきます。

浮動小数点数型と複素数型なら値として複素数型が返ってきます。

/の仕様変更及び//の追加

Python2.2で//が追加されています。

//は商の整数部を返しますが、これは元々/の仕様でした。

/がPython2で問題だったのは、整数で使った場合と浮動小数点数で使った場合で戻ってくる型が異なっていたことです。

整数同士に対して/を用いると切り捨てられた商が返ってきます。一方で、浮動小数点数が含まれると小数点以下も含まれて返ってきました(つまり、浮動小数点数として返ってきました)。

Python3でその役割が/と//で完全に分離されたのです。

以下を参考にしてください

PEP 238: 除算演算子を変更していく

intとlongの統一

Python3以前は整数型には2種類存在していました。

長整数と呼ばれる整数があったのです。

これは整数の後ろにLをつけることで任意のサイズの値が格納できました(intは32ビット)。

Python初期のころはこの仕様によって色々な箇所で不具合があったようです。

Python2.2で必要に応じて、自動的にintをlongに変換するようになりました。

この先のPython2.4ではLを使うと警告がでるようになり、Python3で消えました。

という背景が実はあります。気になる方は以下を参照してください。

PEP 237: 長整数と整数を一体化していく

まとめ

いかがだったでしょうか

優先順位は覚える必要はありませんが、時々確認したいときに便利なのでまとめました。

実際は複雑になれば括弧でくくって読み手に分かりやすくしますので、絶対覚えるべきものでは有りません。

あと今回は関数には触れていません。

また関数に関しての記事を書き次第、修正したいと思います。

それでは以上になります!ありがとうございました。

【Python】演算子の優先順位

今回は、Pythonの演算子の優先順位についてまとめたいと思います。

演算子について

  1. 演算子の優先順位
  2. 注意点・Tips

演算子の優先順位

とりあえず、公式サイトからPython3.7時点では以下のようになっています。

演算子 説明
lambdaラムダ式
if/else条件式
orブール演算 OR
andブール演算 AND
not xブール演算 NOT
in, not in, is, is not, <, <=, >, >=, !=, ==所属や同等、同一性のテストなどの比較
|ビット単位 OR
^ビット単位 XOR
&ビット単位 AND
<<, >>シフト演算
+, –加算および減算
*, @, /, //, %乗算、行列乗算、除算、切り捨て除算、剰余
+x, -x, ~x正数、負数、ビット単位 NOT
**べき乗
await xAwait 式
x[i], x[a:b], func(arg…), obj.attr添字指定、スライス操作、呼び出し、属性参照
(式), [式…], {key: value…}, {式…}式結合またはタプル表示、リスト表示、辞書表示、集合表示

参考: 6. 式 (expression) — Python 3.7.4rc1 ドキュメント

注意点・Tips

Pythonは常に進化しています。従って、この優先順位にも追加されたり、削除されたりしています。

私の知っている限りをここに書いていきます。

//の2.2追加

2.2から小数を切り捨てて整数とする「//」が追加されました。

ただし、Python2では「/」は切り捨てでした。これはPythonの初期からある仕様で、議論の的になっていたようです。

それをなくすために段階的に導入されていった経緯があります。いきなり、整数を返すのではなく、浮動小数点数を返すようになったら、動かなくなるコードが多かったのです。

Python3で//は切り捨ての整数を返すようになり、/は浮動小数点数表現で可能な限り値を表現してくれます。

詳しくは以下をご覧ください。

PEP 238 – 除算演算子を変更していく

https://www.python.org/dev/peps/pep-0238/

<>のPython3で削除

同じ意味合いのものとして!=があります。

<>はデータベースで使うキーワードですね。

おそらく、同じ意味のキーワードがあると、使う人によって実装が異なってしまい、可読性が下がるのじゃないでしょうか。

Pythonの思想的にNGだったのでしょうね。

`・・・`のPython3で削除

これはインタープリタ内のオブジェクトを出力します。

対話型インタプリタで直接オブジェクトだけ入力したときに値が返ってきますよね?あれです。内部で__ repr __にアクセスしています。

これも<>と同じような理由だと思います。

repr関数があるので、それを使いましょう。

醜いより美しいが良いですね。

await文をPython3.5から追加

これは時代の流れを感じます。

非同期処理を言語使用として組み込み始めました。

@演算子の追加3.5

これは、機械学習のほうの流れを汲んでいるのでしょうか。

行列の乗算にたいして行われます。

ただし、ビルトインの型では実装されていません。

使うときは__matmul__を実装すればよいみたいです。

まとめ

いかがだったでしょうか?

おそらく、私が知らないものや漏れているものもあると思いますので順次追加していきたいと思います。

ただ、処理順序は覚えなくて大丈夫です。その都度確認すればいいですし、なにより括弧つければいいだけですので・・・

以上になります。

それではみなさんのPythonライフがよりよくなるように祈ってます!