Why is using 'eval' a bad practice?

I am using the following class to easily store data of my songs.

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()

I feel that this is just much more extensible than writing out an if/else block. However, eval seems to be considered a bad practice and unsafe to use. If so, can anyone explain to me why and show me a better way of defining the above class?


Yes, using eval is a bad practice. Just to name a few reasons:

  • There is almost always a better way to do it
  • Very dangerous and insecure
  • Makes debugging difficult
  • Slow
  • In your case you can use setattr instead:

    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)
    

    EDIT:

    There are some cases where you have to use eval or exec. But they are rare. Using eval in your case is a bad practice for sure. I'm emphasizing on bad practice because eval and exec are frequently used in the wrong place.

    EDIT 2:

    It looks like some disagree that eval is 'very dangerous and insecure' in the OP case. That might be true for this specific case but not in general. The question was general and the reasons I listed are true for the general case as well.

    EDIT 3: Reordered point 1 and 4


    Using eval is weak, not a clearly bad practice.

  • It violates the "Fundamental Principle of Software". Your source is not the sum total of what's executable. In addition to your source, there are the arguments to eval , which must be clearly understood. For this reason, it's the tool of last resort.

  • It's usually a sign of thoughtless design. There's rarely a good reason for dynamic source code, built on-the-fly. Almost anything can be done with delegation and other OO design techniques.

  • It leads to relatively slow on-the-fly compilation of small pieces of code. An overhead which can be avoided by using better design patterns.

  • As a footnote, in the hands of deranged sociopaths, it may not work out well. However, when confronted with deranged sociopathic users or administrators, it's best to not give them interpreted Python in the first place. In the hands of the truly evil, Python can a liability; eval doesn't increase the risk at all.


    In this case, yes. Instead of

    exec 'self.Foo=val'
    

    you should use the builtin function setattr :

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

    上一篇: 如何在JavaScript中将十进制转换为十六进制?

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