どうも日本語コーディングが出来ない

日本語の変数名とかメソッド名とかクラス名といった識別子が使えないっぽい。

日本語でかけると良いんだけど。

できるという記事をどっかで見たような気もするんだけどなぁ。

まぁ、

識別子 (または 名前 (name)) は、以下の字句定義で記述されます:

identifier ::= (letter|”_”) (letter | digit | “_”)*

letter ::= lowercase | uppercase

lowercase ::= “a”…”z”

uppercase ::= “A”…”Z”

digit ::= “0”…”9″

http://www.pinkdragon.net/doc_lib/contents/ja/python_man/ref/identifiers.html

を見る限りは出来ないで正解だとは思うんだけど。

FacebookTwitterHatenaTumblr共有

外側のコードブロックの変数が見れなくなる理由がやっとわかった

と言われてしまった。

どうも、このままだと外側のコードブロックにある変数を見てくれないらしい。

だから、どうやってやるんだろうといろいろと調べていたら、どうも、下記コードのように配列とすると、外側のコードブロックにある変数にアクセスできるっぽい。

Pythonでのクロージャについて(追記あり) – NAL-6295の舌先三寸

で悩んでいた問題は

ある名前がブロック内で束縛されている場合、名前はそのブロックに おけるローカル変数 (local variable) です。 ある名前がモジュールレベルで束縛されている場合、名前は グローバル変数 (global variable) です。 (モジュールコードブロックの変数は、ローカル変数でもあるし、 グローバル変数でもあります。) ある変数がコードブロック内で使われているが、そのブロックでは定義 されていない場合、変数は 自由変数 (free variable)です。

4.1 名前づけと束縛 (naming and binding)

という事で、同じ名前の変数を使うと、そのブロックで新しく作られ、そのブロック全体で有効になるんですね。

リファレンス見ないでやっていたら3分くらいクラスのメソッドが動かなくて悩んだ

リファレンス見ないで昨日のスクリプトをクラスで実装してみた。

"ナベアツ問題"
class nabeatsuQuestion:
def createReader(self):
"ナベアツ問題を読み上げる人を作る"
def reader():
"読み上げる人"
def isFool(value):
"3の倍数と3の付くときあほである"
if value % 3 == 0:
return True
if str(value).find('3') >= 0:
return True
def isDog(value):
"5の倍数で犬である"
return value % 5 == 0
outputValue = ''
if isFool(reader.value):
outputValue += 'fool!'
if isDog(reader.value):
outputValue += 'bow-wow!'
if outputValue == '':
outputValue += str(reader.value)
print outputValue
reader.value += 1
return reader
reader.value = 1
return reader
instance = nabeatsuQuestion()
runner = instance.createReader()
for i in xrange(1,40,1):
runner()

そうしたら、instance. createReader()のところで引数がどうのこうのって言われたので、小3分くらい悩んだ。

どうも、引数にselfを用意しておかないといけないようで。

"ナベアツ問題"
class nabeatsuQuestion:
def createReader(self):
"ナベアツ問題を読み上げる人を作る"
def reader():
"読み上げる人"
def isFool(value):
"3の倍数と3の付くときあほである"
if value % 3 == 0:
return True
if str(value).find('3') >= 0:
return True
def isDog(value):
"5の倍数で犬である"
return value % 5 == 0
outputValue = ''
if isFool(reader.value):
outputValue += 'fool!'
if isDog(reader.value):
outputValue += 'bow-wow!'
if outputValue == '':
outputValue += str(reader.value)
print outputValue
reader.value += 1
return reader
reader.value = 1
return reader
instance = nabeatsuQuestion()
runner = instance.createReader()
for i in xrange(1,40,1):
runner()

としたら動いた。

リファレンスはちゃんと読もうという教訓。

#はてな記法って便利

Pythonでのクロージャについて(追記あり)

Pythonでリファレンスを見ながら初めてコーディングしたためクロージャの実装で悩んだ。

最初、C#とかと同じ乗りで

def nabeatsu():
    value = 1
    def reader():
        isAho = value % 3 == 0 or str(value).find('3') >= 0
        isDog = value % 5 == 0
        if isAho:
            print 'あほ'
        if isDog:
            print 'わん!'
        if not isAho and not isDog:
            print value
        value = value + 1 #5/10まで間違ったサンプルになっていたのを修正(5/11)
        return reader
runner = nabeatsu()
for value in xrange(1,40,1):
    runner()

としたら、runner()を実行したときに、

valueなんてローカル変数無いよ。

と言われてしまった。

どうも、このままだと外側のコードブロックにある変数を見てくれないらしい。

だから、どうやってやるんだろうといろいろと調べていたら、どうも、下記コードのように配列とすると、外側のコードブロックにある変数にアクセスできるっぽい。

def nabeatsu():
    value = [0]
    value[0] = 1
    def reader():
        isAho = value[0] % 3 == 0 or str(value[0]).find('3') >= 0
        isDog = value[0] % 5 == 0
        if isAho:
            print 'あほ'
        if isDog:
            print 'わん!'
        if not isAho and not isDog:
            print value[0]
        value[0] = value[0] + 1
        return reader
runner = nabeatsu()
for value in xrange(1,40,1):
    runner()

でも、配列にする必要が無いので、ちょっと気持ち悪いと思って更に調べたら定義した関数にプロパティを持つことが可能らしく、結局下記のコードで落ち着いた。

追記:

下記の例でPythonのクロージャとして落ち着いたと書きましたが、runner = nabea2()でファンクションを取得した後、runner.value = 値で外部から変更できてしまうので(つまりvalueのスコープが広すぎる。)、結局、二つ目の配列を使った例が(気持ち悪いけど)クロージャなのかなと。

def nabea2():
    def reader():
        isAho = reader.value % 3 == 0 or str(reader.value).find('3') >= 0
        isDog = reader.value % 5 == 0
        if isAho:
            print 'あほ'
        if isDog:
            print 'わん!'
        if not isAho and not isDog:
            print reader.value
        reader.value += 1
    reader.value= 1
    return reader
runner = nabea2()
for value in xrange(1,40,1):
    runner()

nabea2メソッドの中でreaderメソッドを定義し、その後readerメソッドをreaderメソッドのvalueという名前のプロパティを1に初期化した上で戻り値として返しています。