Skip to content

Instantly share code, notes, and snippets.

@sugarflower
Last active July 3, 2019 09:19
Show Gist options
  • Save sugarflower/c34d679d9302fed79d9171965d2dc93b to your computer and use it in GitHub Desktop.
Save sugarflower/c34d679d9302fed79d9171965d2dc93b to your computer and use it in GitHub Desktop.

親モジュールにファンクションが存在するか知りたい

ついでにArduinoやProcessingみたいに setup だとか loopdraw みたいに簡単にコードが書けてループ処理が隠蔽出来ると最高。

child.py

#!/usr/bin/python3
import inspect

def getParent():
	s = inspect.stack()
	for i in s:
		if (i[3] == "<module>") & (i[1] != "<stdin>"):
			_parent = inspect.getmodule(i[0])
	return _parent

def isDef( funcName ):
	p = getParent()
	d = set(dir(p))
	return len(d & {funcName}) == 1

前ポストのgetParentを使い親のモジュールを取得してdirでファンクション一覧を取得。存在するか見ているだけで簡単。

ただし、これをどのタイミングで動かすかが問題。

import child

print(child.isDef("hello"))

def hello():
	print("hello")

これは動かない例。

import child

def hello():
	print("hello")

print(child.isDef("hello"))

こっちは動く例。

HTML5とかのDOMの感覚といえばいいのかな。

気持ち的にはモジュールを読み込んだ時点で走査したいのだけれどもまだ呼び出し元のモジュール全体が読まれていないのでそれは出来ないということ。

正常に動作させるためには呼び出し元モジュールが全て読み込み終わってからでないといけない。

Pythonにプロトタイプ宣言はない

ないものはないので仕方がない、でも煩わしさは出来る限り取り除きたい。

child.py

#!/usr/bin/python3
import inspect

def getParent():
	s = inspect.stack()
	for i in s:
		if (i[3] == "<module>") & (i[1] != "<stdin>"):
			_parent = inspect.getmodule(i[0])
	return _parent

def isDef( funcName ):
	p = getParent()
	d = set(dir(p))
	return len(d & {funcName}) == 1
  
def run():
	if isDef("loop"):
		p = getParent()
		p.loop()

main.py

import child

def loop():
	print("hello")

child.run()

なんか釈然としないけれどこれがスマートかな? 思い返してみればこういう作りしてるの多い気がする。

@sugarflower
Copy link
Author

sugarflower commented Jul 3, 2019

getParent の処理、内容はスタックトレースなので最後の行が起点にしかならない気がしてきた。
つまり

s = inspect.stack()
parent = inspect.getmodule( s[ len( s )-1 ][0] )

これでいいんじゃないかと。
つまりこれでOK?

child.py

import inspect
def run():
	s = inspect.stack()
	p = inspect.getmodule( s[ len( s )-1 ][0] )
	d = set(dir(p))
	if len(d & {"setup"} ) == 1:
		p.setup()	
	if len(d & {"loop"} ) == 1:
		p.loop()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment