今天因重构代码需要,发现了一种巧妙的方法实现模块级别的"重载",即重新实现模块中的若干内部函数的功能得到一个新模块。
使用方法为:
a.py
==========
def bar():
return 'bar in a'
def foo():
print bar()
===========
b.py
============
from a import *
from luzong.utils import callby
@callby(foo)
def bar():
return 'bar in b'
============
测试
=========
>>> import a, b
>>> a.foo()
bar in a
>>> b.foo()
bar in b
=========
callby 的实现也非常简单:
====================
def clone_func(f, g):
"inspect a func f with globals g"
return f.__class__(f.func_code, g, f.func_name, f.func_defaults)
def callby(caller):
"auto inspect callers for a function"
def deco(f):
g = f.func_globals
callers = [caller,] if not isinstance(caller, (list, tuple)) else caller
for c in callers:
if c.func_globals is not g:
g[c.func_name] = clone_func(c, f.func_globals)
return f
return deco
====================
- Davies
--
来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
详情: https://groups.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
callby这种用法很不好理解,不直观,我的建议是直接定义foo,如果它调用的bar不是a.py的,则再定主乐bar不是更好。从上例来看,foo本身可能是不变的,但是它调用的bar却发生了变化。但是不如重新定义foo这样更让人容易理解a.py,
b.py之间的差异。如果要是再复杂,那还不如直接使用class呢,更清晰。
--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://uliwebproject.appspot.com
My Blog: http://hi.baidu.com/limodou
> --
> 来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
> 退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
> 详情: https://groups.google.com/group/python-cn
> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
>
--
http://zoomquiet.org 人生苦短? Pythonic!
是也乎,是也乎,能够进行这种发现是好的,
只是,最后,想得到简洁的可复用,清晰的代码,还是简单点来比较好...
感觉你没理解LZ要的是什么。
他之所以叫“重载”,是因为,你调用b的foo使用的是b的bar,但你调用a的foo的时候,使用的应该是a的bar。
看看他的测试用例吧:
=========
>>> import a, b
>>> a.foo()
bar in a
>>> b.foo()
bar in b
=========
你的程序做不到这一点的。
--
Best Regards,
Leo Jay
--
Best Regards,
Leo Jay
--
来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
详情: https://groups.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
楼主本来就是在误用“重载”这个词,你跟着误用,无语。。。
重载这个词是指同一个函数给定不同参数时具有不同的行为,覆盖是指通过继承之后重写相关函数来替换相关功能的办法。python中根本不支持重载。只支持覆盖。
重载只可能在 C++ 之类强类型检查的语言中出现,而且重载会导致 ABI 的 name mangling
问题(连接库中的名字跟函数真实名字不同)。python 这种语言中不可能写两个一模一样的函数具有不同参数还能同时生效。
Hi,
今天因重构代码需要,发现了一种巧妙的方法实现模块级别的"重载",即重新实现模块中的若干内部函数的功能得到一个新模块。
使用方法为:
a.py
==========
def bar():
return 'bar in a'
def foo():
print bar()
===========
b.py
============
from a import *
from luzong.utils import callby
@callby(foo)
def bar():
return 'bar in b'
--
来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
详情: https://groups.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
--
--
http://zoomquiet.org 人生苦短? Pythonic!
嗯嗯,sorry,说错。
历史原因,一直对重载对应overload还是override不清楚。
> 重载这个词是指同一个函数给定不同参数时具有不同的行为,覆盖是指通过继承之后重写相关函数来替换相关功能的办法。python中根本不支持重载。只支持覆盖。
>
> 重载只可能在 C++ 之类强类型检查的语言中出现,而且重载会导致 ABI 的 name mangling
> 问题(连接库中的名字跟函数真实名字不同)。python 这种语言中不可能写两个一模一样的函数具有不同参数还能同时生效。
>
就算你导出一个最简单的void foo(),没有overload也会被mangle的。
因地制宜,活学活用!