質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

1回答

1449閲覧

python3のコードの振る舞いがわからないので教えていただけますでしょうか。

mmmisaki

総合スコア34

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2017/11/19 15:33

###前提・実現したいこと

python3のコードの振る舞いがいまいちわからないです

以下のコードの
best = genetic.get_best(fnGetFitness, len(target), optimalFitness,self.geneset, fnDisplay)
という関数の部分なんですがget_best関数に渡すfnGetFitness,fnDisplayの引数が定義されてないままget_best関数に渡しているように見えます。
実際直前にprintで引数を出力させても
<function GuessPasswordTests.guess_password.<locals>.fnGetFitness at 0x7f8edfe44378>
38
38
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!.,
<function GuessPasswordTests.guess_password.<locals>.fnDisplay at 0x7f8edfe446a8>
5
(5つprintしたのに6つ出力されているのも何故なんでしょうか)
となります。

呼び出されたget_best関数内で引数を出力しても同様<functin 以下略>となります。しかし最終的にはしっかり文字列が出力されています。

unittestだと特別な処理方法をしてコードの実行順番が違うのか わからなくて困っております。
以下の実際のコードの振る舞いを教えていただけますでしょうか。

###実際のコード

import datetime import random import unittest import genetic def get_fitness(guess, target): return sum(1 for expected, actual in zip(target, guess) if expected == actual) def display(candidate, startTime): timeDiff = datetime.datetime.now() - startTime print("{}\t{}\t{}".format( candidate.Genes, candidate.Fitness, timeDiff)) class GuessPasswordTests(unittest.TestCase): geneset = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!.," def test_Hello_World(self): target = "machine learning in genetic algorithm!" self.guess_password(target) def guess_password(self, target): startTime = datetime.datetime.now() def fnGetFitness(genes): return get_fitness(genes, target) def fnDisplay(candidate): display(candidate, startTime) optimalFitness = len(target) # print(fnGetFitness) # print(len(target)) # print(optimalFitness) # print(self.geneset) # print(fnDisplay) best = genetic.get_best(fnGetFitness, len(target), optimalFitness, self.geneset, fnDisplay) self.assertEqual(best.Genes, target) if __name__ == '__main__': unittest.main()
import random import statistics import sys import time def _generate_parent(length, geneSet, get_fitness): genes = [] while len(genes) < length: sampleSize = min(length - len(genes), len(geneSet)) genes.extend(random.sample(geneSet, sampleSize)) genes = ''.join(genes) fitness = get_fitness(genes) return Chromosome(genes, fitness) def _mutate(parent, geneSet, get_fitness): index = random.randrange(0, len(parent.Genes)) childGenes = list(parent.Genes) newGene, alternate = random.sample(geneSet, 2) childGenes[index] = alternate if newGene == childGenes[index] else newGene genes = ''.join(childGenes) fitness = get_fitness(genes) return Chromosome(genes, fitness) def get_best(get_fitness, targetLen, optimalFitness, geneSet, display): random.seed() bestParent = _generate_parent(targetLen, geneSet, get_fitness) display(bestParent) if bestParent.Fitness >= optimalFitness: return bestParent while True: child = _mutate(bestParent, geneSet, get_fitness) if bestParent.Fitness >= child.Fitness: continue display(child) if child.Fitness >= optimalFitness: return child bestParent = child class Chromosome: def __init__(self, genes, fitness): self.Genes = genes self.Fitness = fitness class Benchmark: @staticmethod def run(function): timings = [] stdout = sys.stdout for i in range(100): sys.stdout = None startTime = time.time() function() seconds = time.time() - startTime sys.stdout = stdout timings.append(seconds) mean = statistics.mean(timings) if i < 10 or i % 10 == 9: print("{} {:3.2f} {:3.2f}".format( 1 + i, mean, statistics.stdev(timings, mean) if i > 1 else 0))

###補足情報(言語/FW/ツール等のバージョンなど)
python3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Pythonでは関数もオブジェクトの一つなので、そのまま渡せます。

Python

1def high(func): 2 func('spam') 3 4def hoge(s): 5 print(s * 2) 6 7def fuga(s): 8 print(s[:-1]) 9 10high(hoge) 11high(fuga) 12 13"""出力 14spamspam 15spa 16"""

これはかなりシンプルな例ですが、引数は呼び出す際にあればよいことが分かります。

ご提示のコードの挙動を完全に理解するには、クロージャについて知る必要がありますが...
まあ、とりあえず『関数そのもの』を渡していることがわかれば大丈夫です。


get_best関数内で引数を出力しても同様<functin 以下略>となります

『関数そのもの』を出力すると、そのように表示されます。至って正常な動作です。

Python

1>>> print(hoge) 2<function hoge at 0x0000020E078FBAE8>

5つprintしたのに6つ出力されているのも何故なんでしょうか

試してみましたが、最後の『5』は表示されませんでした。
なにか別の出力を混同したのではないでしょうか?

投稿2017/11/19 15:48

編集2017/11/19 15:52
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mmmisaki

2017/11/19 15:59

お早い回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問