例如。
我能否在代码内部执行此操作?
是否有静态分析工具具有此功能?
编辑:
我想为Python 2.5应用程序使用它,但事实证明这不是真正可能的,因为:
1.2.5不支持“unicode_literals” 2.kwargs字典键不能是unicode对象,只能是字符串
因此,即使出于不同的原因,我也接受说这是不可能的答案 :)
我觉得你需要使用一个真正的Python解析器来解析代码。然后,你需要深入分析解析器生成的AST,看看它是否包含任何字符串字面量。
看起来Python自带一个解析器。从这个文档中,我得到了以下代码示例:
import parser
from token import tok_name
def checkForNonUnicode(codeString):
return checkForNonUnicodeHelper(parser.suite(codeString).tolist())
def checkForNonUnicodeHelper(lst):
returnValue = True
nodeType = lst[0]
if nodeType in tok_name and tok_name[nodeType] == 'STRING':
stringValue = lst[1]
if stringValue[0] != "u": # Kind of hacky. Does this always work?
print "%s is not unicode!" % stringValue
returnValue = False
else:
for subNode in [lst[n] for n in range(1, len(lst))]:
if isinstance(subNode, list):
returnValue = returnValue and checkForNonUnicodeHelper(subNode)
return returnValue
print checkForNonUnicode("""
def foo():
a = 'This should blow up!'
""")
print checkForNonUnicode("""
def bar():
b = u'although this is ok.'
""")
打印输出
'This should blow up!' is not unicode!
False
True
现在文档字符串不是Unicode,但应该被允许,因此您可能需要做一些更复杂的事情,例如from symbol import sym_name
,在那里您可以查找哪些节点类型用于类和函数定义。然后,第一个子节点只是一个字符串,即不是赋值或其他内容的一部分,应该被允许不是Unicode。
好问题!
编辑
只是一个跟进评论。方便起见,parser.suite
实际上不会评估您的Python代码。这意味着您可以在不担心命名或导入错误的情况下运行此解析器来处理Python文件。例如,假设您有一个包含以下内容的myObscureUtilityFile.py
from ..obscure.relative.path import whatever
你可以
checkForNonUnicode(open('/whoah/softlink/myObscureUtilityFile.py').read())
你不能强制所有字符串都是Unicode的;即使在模块中使用了from __future__ import unicode_literals
,字节字符串仍然可以写成b'...'
,就像在Python 3中一样。
曾经有一个选项可以用来全局获取与unicode_literals
相同的效果:命令行选项-U
。但是,在2.x系列早期就被放弃了,因为它基本上破坏了每个脚本。
你的目的是什么?废除字节字符串并不可取。它们并不“坏”,Unicode字符串也不普遍“更好”;它们是两种不同的类型,你需要同时使用它们。字节字符串肯定需要用于访问二进制文件和网络服务。
如果你想准备过渡到Python 3,最好的方法是对于所有你真正想要作为字节的字符串使用b'...'
,对于本质上是Unicode的字符串使用u'...'
。默认字符串'...'
格式可用于其他所有地方,即你不关心和/或Python 3是否更改了默认字符串类型的地方。
我们的SD源代码搜索引擎(SCSE)可以直接提供此结果。
SCSE提供了一种快速搜索大量文件的方法,使用语言结构来实现精确查询和最小化误报。它处理各种语言,甚至同时处理Python。GUI显示搜索命中和包含所选命中的实际文本页面。
它使用源语言的词汇信息作为查询的基础,由各种语言关键字和模式令牌组成,匹配不同的内容语言元素。SCSE知道语言中可用的词素类型。您可以搜索通用标识符(使用查询令牌I)或与某个正则表达式匹配的标识符。同样,您可以搜索通用字符串(使用查询令牌“S”表示“任何类型的字符串文字”)或特定类型的字符串(对于Python,包括“UnicodeStrings”,非Unicode字符串等,这些共同构成了Python事物的集合“S”)。
因此,一个搜索:
'for' ... I=ij*
查找关键字“for”附近(“…”)前缀为“ij”的标识符,并显示所有命中项。忽略特定于语言的空格,包括换行和注释。
一个简单的搜索:
S
查找所有字符串字面量。这通常是一个相当大的集合 :-}
搜索
UnicodeStrings
查找所有以Unicode字符串(u“…”)词法定义的字符串字面量。
您想要的是所有不是Unicode字符串的字符串。SCSE提供了一个“减去”运算符,它可以减去与另一种重叠的一种命中。因此,您的问题“哪些字符串不是Unicode”可以简洁地表达为:
S-UnicodeStrings
所有显示的结果都将是非Unicode字符串,这是您确切的问题。
SCSE提供日志记录功能,以便您可以记录命中情况。您可以从命令行运行SCSE,启用脚本查询以获取答案。将其放入命令脚本中将提供一个直接给出答案的工具。
from __future__ import unicode_literals
- Ignacio Vazquez-Abrams__future__
的编译器指令只会影响当前模块。 - Ignacio Vazquez-Abrams