2015/11/16

[勉][py]やむを得ず覚えるpython (6)

やむを得ずといいながらも6回続けてきたこのコーナー。
今回で終わりにします。

実装するには不十分だけど、「うわっ、python知らないから無理」というところは脱したかなと思う。
あとは、他の言語と同じように、知らないことが出てきたら調べていけばいいだろう。


複数ファイル

sys.stderr.write()なんかは、他で実装された機能を使っている。
importで読込んだような感じはするのだが、まずは自分で複数作って試そう。

 

06.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: functionA()

06a.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: def functionA():
  4:     print("This is functionA.");

$ ./06.py
Traceback (most recent call last):
  File "./06.py", line 3, in <module>
    functionA()
NameError: name 'functionA' is not defined

同じフォルダに06.pyと06a.pyを置いたのだが、それだけではダメだ。
では、importを追加してみよう。

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import 06a
  4: 
  5: 06a.functionA()

$ ./06.py
  File "./06.py", line 3
    import 06a
            ^
SyntaxError: invalid syntax

嘘つき!
みんな、ファイル名をimportしてクラスっぽくすれば呼び出せるって言ってるのに。

06.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import f06a
  4: 
  5: f06a.functionA()

$ mv 06a.py f06a.py
$ ./06.py
This is functionA.

薄々、そんなことじゃないかと思っていたが、数字で始まる名前はクラスとか変数名とかで使えないから、importするものとしても使えない、ということのようだ。

あとですね、これを実行すると「f06a.pyc」というファイルが自動的に作られていた。

image

勝手に作るものなのか?
.pycファイルを作成する方法メモ - かせきのうさぎさん
.pycファイルを作成させない方法メモ - かせきのうさぎさん
作るものらしい。

コンパイルしたものらしいから、じゃあ元ファイルがなくても実行できるのか?

$ rm f06a.py
$ ./06.py
This is functionA.

できるんだ。

お互いを呼び出すような関係にはできる?

f06.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import f06a
  4: 
  5: def functionB():
  6:     print("This is functionB.")
  7: 
  8: if __name__ == "__main__":
  9:     f06a.functionA()

f06a.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import f06
  4: 
  5: def functionA():
  6:     f06.functionB()
  7:     print("This is functionA.")

$ ./f06.py
This is functionB.
This is functionA.

特にないようだ。
ただ、f06.pyに__name__=="__main__"のif文がないと、こうなる。

$ ./f06.py
Traceback (most recent call last):
  File "./f06.py", line 3, in <module>
    import f06a
  File "/cygdrive/e/Prog/python/study/f06a.py", line 3, in <module>
    import f06
  File "/cygdrive/e/Prog/python/study/f06.py", line 9, in <module>
    f06a.functionA()
AttributeError: 'module' object has no attribute 'functionA'

たぶん、

  • 06.pyの3行目のimportで、06a.pyを読込み始める
  • 06a.pyの3行目のimportで、06.pyを読込み始める
  • 06.pyの3行目のimportはもう読込み始めているのでスルーする
  • 地の文の「f06a.functionA()」にたどり着くが、まだ06a.pyの読込みは3行目で止まっているので「functionAはないよ」というエラーを出す

ということじゃなかろうか。


あとは、タプルとかC/C++の言語仕様にはないものがあるが、出てきたときに調べればいいだろう。

なんとなく満足したので、終了!

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。