为什么使用'eval'是一种不好的做法?

我使用以下课程轻松存储我的歌曲数据。

class Song:
    """The class to store the details of each song"""
    attsToStore=('Name', 'Artist', 'Album', 'Genre', 'Location')
    def __init__(self):
        for att in self.attsToStore:
            exec 'self.%s=None'%(att.lower()) in locals()
    def setDetail(self, key, val):
        if key in self.attsToStore:
            exec 'self.%s=val'%(key.lower()) in locals()

我觉得这比写出一个if/else块更具可扩展性。 然而, eval似乎被认为是不好的做法,并且不安全。 如果是这样,任何人都可以向我解释为什么,并告诉我一个更好的方式来定义上面的类?


是的,使用eval是一种不好的做法。 仅举几个原因:

  • 几乎总是有一个更好的方法来做到这一点
  • 非常危险和不安全
  • 使调试变得困难
  • 在你的情况下,你可以使用setattr来代替:

    class Song:
        """The class to store the details of each song"""
        attsToStore=('Name', 'Artist', 'Album', 'Genre', 'Location')
        def __init__(self):
            for att in self.attsToStore:
                setattr(self, att.lower(), None)
        def setDetail(self, key, val):
            if key in self.attsToStore:
                setattr(self, key.lower(), val)
    

    编辑:

    有些情况下,您必须使用eval或exec。 但他们很少见。 在你的情况下使用eval肯定是一种不好的做法。 我强调不好的做法,因为eval和exec经常用在错误的地方。

    编辑2:

    看起来有些人不同意在OP案中eval是“非常危险和不安全”的。 对于这种特殊情况可能是这样,但一般情况并非如此。 这个问题是一般的,我列出的理由也适用于一般情况。

    编辑3:重新排序点1和4


    使用eval很弱,不是一个明显不好的做法。

  • 它违反了“软件的基本原则”。 您的来源不是可执行文件的总和。 除了你的来源,还有一些eval的论点,必须清楚地理解。 出于这个原因,这是最后的手段。

  • 这通常是无意识设计的标志。 对于动态构建的动态源代码,很少有很好的理由。 使用委托和其他面向对象设计技术几乎可以做任何事情。

  • 它导致相对较慢的即时编译小部分代码。 可以通过使用更好的设计模式避免的开销。

  • 作为一个脚注,在疯狂的反社会人士手中,它可能无法奏效。 但是,当面对疯狂的社交用户或管理员时,最好不要给他们解释Python。 在真正的邪恶手中,Python可能是一种责任; eval不会增加风险。


    在这种情况下,是的。 代替

    exec 'self.Foo=val'
    

    你应该使用内建函数setattr

    setattr(self, 'Foo', val)
    
    链接地址: http://www.djcxy.com/p/31763.html

    上一篇: Why is using 'eval' a bad practice?

    下一篇: Check if local git repo is ahead/behind remote