草庐IT

python - 在列表项错误之间发出缺少逗号的警告

coder 2023-05-23 原文

故事:

在多行中定义字符串列表时,通常很容易忘记列表项之间的逗号,例如在以下示例中:

test = [
    "item1"
    "item2"
]

现在,列表test将只有一个项目"item1item2"

重新排列列表中的项目后,经常会出现问题。

具有以下问题的样本堆栈溢出问题:
  • Why do I get a KeyError?
  • Python - Syntax error on colon in list

  • 问题:

    有没有一种方法,最好是使用静态代码分析,在这种情况下发出警告,以便尽早发现问题?

    最佳答案

    这些只是可能的解决方案,因为我不太喜欢静态分析。

    tokenize:

    我最近在摆弄with tokenizing python code,我相信添加足够的逻辑后,它便具有执行此类检查所需的所有信息。对于给定的列表,使用python -m tokenize list1.py生成的 token 如下:

    python -m tokenize list1.py 
    
    1,0-1,4:    NAME    'test'
    1,5-1,6:    OP  '='
    1,7-1,8:    OP  '['
    1,8-1,9:    NL  '\n'
    2,1-2,8:    STRING  '"item1"'
    2,8-2,9:    NL  '\n'
    3,1-3,8:    STRING  '"item2"'
    3,8-3,9:    NL  '\n'
    4,0-4,1:    OP  ']'
    4,1-4,2:    NEWLINE '\n'
    5,0-5,0:    ENDMARKER   ''
    

    当然,这是“问题”情况,其中内容将被连接在一起。在存在,的情况下,输出会略有变化以反射(reflect)这一点(我仅为列表主体添加了标记):
    1,7-1,8:    OP  '['
    1,8-1,9:    NL  '\n'
    2,1-2,8:    STRING  '"item1"'
    2,8-2,9:    OP  ','
    2,9-2,10:   NL  '\n'
    3,1-3,8:    STRING  '"item2"'
    3,8-3,9:    NL  '\n'
    4,0-4,1:    OP  ']'
    

    现在,我们有了附加的OP ',' token ,该 token 表示第二个元素的存在,以逗号分隔。

    有了这些信息,我们可以在generate_tokens模块中使用真正方便的方法tokenize。方法 tokenize.generate_tokens() (即tokenize.tokenize()中的Py3)具有单个参数readline,这是一种针对类文件对象的方法,该方法实质上返回该文件的下一行对象(relevant answer)。它返回一个共有5个元素的命名元组,其中包含有关 token 类型, token 字符串以及行号和行中位置的信息。

    使用此信息,理论上可以遍历文件,并且列表初始化内不存在OP ','(通过检查 token NAMEOP '='OP '['是否位于同一行号来检测开头)时,可以在该文件上发出警告。检测到的行。

    这种方法的好处是概括起来很简单。为了适应发生字符串文字串联的所有情况(即在'grouping'运算符(), {}, []内),请检查 token 是否为 type = 51 (或53 for Python 3)或同一行中是否存在(, [, {中的任何值(这些值是粗糙的,最重要的建议是atm)。

    现在,我不太确定其他人如何解决这些问题,但是似乎可以研究一下。所需的所有信息均由tokenize提供,检测它的逻辑是唯一缺少的东西。

    实现注意:这些值(例如,type)在版本之间确实有所不同,并且可能会发生变化,因此应该注意这一点。但是,可以将by only working with constants用于 token 。

    使用parserast:

    另一个可能更乏味的解决方案可能涉及 parser ast 模块。字符串的连接实际上是在抽象语法树的创建过程中执行的,因此您可以在那儿进行检测。

    我真的不想转储我要提到的parserast方法的完整输出,但是,为了确保我们位于同一页面上,我将使用以下列表初始化语句:
    l_init = """
    test = [
        "item1"
        "item2",
        "item3"
    ]
    """
    

    为了获得生成的解析树,请使用 p = parser.suite(l_init) 。完成此操作后,您可以使用 p.tolist() 对其进行查看(输出太大而无法添加)。您会注意到,对于三种不同的str对象item1item2item3,将有三个条目。

    另一方面,当使用 node = ast.parse(l_init) 创建AST并使用 ast.dump(node) 查看AST时,只有两个条目:一个用于串联的stritem1item2,另一个用于item3的另一个条目。

    因此,这是另一种可行的方法,但是,正如我之前提到的那样,它更繁琐。我不确定线路信息是否可用,您是否处理两个不同的模块。如果您想使用编译器链中更高级别的内部对象,请回想一下。

    结束语:作为结束语,在这种情况下,tokenize方法似乎是最合乎逻辑的方法。但是相反,似乎pylint实际上可以与 astroid 一起使用,这是一个python库,可以简化对python代码的抽象语法树的分析。因此,理想情况下应该查看它以及如何使用inside pylint

    注意:当然,我可能完全对它进行了过度分析,并且你们建议一个更简单的“检查空白或换行符”解决方案即可。 :-)

    关于python - 在列表项错误之间发出缺少逗号的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34540634/

    有关python - 在列表项错误之间发出缺少逗号的警告的更多相关文章

    1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

      大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

    3. ruby - 用逗号、双引号和编码解析 csv - 2

      我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

    4. ruby-on-rails - Rails 应用程序之间的通信 - 2

      我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

    5. ruby - 在院子里用@param 标签警告 - 2

      我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

    6. ruby - RVM 使用列表[0] - 2

      是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

    7. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

      我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

    8. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

      最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

    9. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

      我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

    10. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

      我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

    随机推荐