背景
在 Verilog 中,我可以使用包含下划线的表达式来指定二进制数。例如:
12'b1100_0111_0001 == 12'b110001110001 // The underscores are ignored
我发现这是一个很好的特性,并想将它添加到 Python 中,这样我就可以编写如下内容:
x = 0b1100_0111_0001
y = 0x3fff_cc00
在 Lisp 中,我可以使用 set-dispatch-macro-character 之类的东西来做到这一点,以便能够在通过阅读器宏编译源代码之前对其进行编辑。
问题
在 Python 中添加类似 Lisp 的阅读器宏的好方法是什么?
对于用我当前的方法或完全不同的方法解决问题的建议,我同样会很高兴。
我尝试过的
我已尝试将自定义查找器对象添加到 sys.meta_path。这几乎可以工作,除了两个问题:
- 当我使用自定义查找器导入模块时,它不存储文件的 pyc 编译表示
- 理想情况下,我希望阅读器宏应用于顶层文件的其余部分,而不是必须将我的代码放入单独的文件“verilog_test_code.py”
源代码
verilog_test_code.py
def run_test():
return 0b1100_0111_0001+0x3fff_cc00
toplevel.py
import remove_underscores
import verilog_test_code
print verilog_test_code.run_test()
remove_underscores.py
import tokenize,sys,imp
def remove_underscores(src):
"""Remove underscores from hexadecimals."""
result = []
g = tokenize.generate_tokens(src.readline)
for toknum, tokval, _, _, _ in g:
if toknum == tokenize.NAME and tokval[0]=='_' and result and result[-1][0]==tokenize.NUMBER:
result[-1][1] = str(result[-1][1]) + tokval[1:].replace('_','')
else:
result.append([toknum, tokval])
return tokenize.untokenize(result)
class my_finder_loader(object):
def is_package(self, fullname):
return False
def get_code(self, fullname):
return compile(self.get_source(fullname),fullname,'exec')
def get_source(self, fullname):
(src, pathname, description) = imp.find_module(fullname)
srctext = remove_underscores(src)
src.close()
return srctext
def load_module(self, fullname):
if fullname in sys.modules:
return sys.modules[fullname]
code = self.get_code(fullname)
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<%s>" % self.__class__.__name__
mod.__loader__ = self
mod.__package__ = ''
exec(code, mod.__dict__)
return mod
def find_module(self, fullname, path=None):
if not fullname.startswith('verilog_'):
return None
return self
sys.meta_path.append(my_finder_loader())
最佳答案
class BinaryUnderscorifier(object):
def __getattr__(self, name):
return int(name.replace('_', ''), 2)
b = BinaryUnderscorifier()
print b._1100_0111_0001 == 0b110001110001 # prints "True"
当然,b._1100_0111_0001
的反汇编与0b110001110001
的反汇编有很大不同,可能是例如对你来说是一个性能打击,但希望不会。
关于python - 如何向 Python 添加阅读器宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21945719/