简体   繁体   中英

How can I evaluate a string into an object in Python?

I am working on creating a Django forums project and I have a "settings" app which access the database for a table called settings.

The table is setup with a verbose_name , name , and value columns. The first is simply a name to be displayed to admins, the second is the name that the setting is accessed by (and is the primary key on the table.)

Now, I have some settings which are boolean, some which are integers, and some of which are string. However, value is a TEXT type in the Database so Django is returning it as a string. Right now I have this implementation to convert booleans into the Python boolean type:

class SettingsMiddleware:
    def process_request(self, request):
        request.settings = {}
        settings = Setting.objects.all()

        for setting in settings:
            if setting.value == ("True" or "1"):
                setting.value = True
            if setting.value == ("False" or "0"):
                setting.value = False

            request.settings[setting.name] = setting.value

        return None

So I have two questions:

  1. Is there a better way to go about this?
  2. How can I determine whether the string contains an integer? I know that I can convert it to an integer with int() if it is valid, but how can I tell whether or not it is valid?

Obviously, regarding question number two, I would remove the or "1" and or "0" bits of the current evaluation.

It seems to me that ast.literal_eval might be useful to you.

>>> import  ast
>>> ast.literal_eval("1")
1
>>> ast.literal_eval("0")
0
>>> ast.literal_eval("True")
True
>>> ast.literal_eval("False")
False
>>> ast.literal_eval("'foobar'")
'foobar'
>>> ast.literal_eval("1.2")
1.2
>>> ast.literal_eval("1.2e3")
1200.0
>>> ast.literal_eval("1,2")
(1, 2)
>>> ast.literal_eval("[1,2]")
[1, 2]
>>> ast.literal_eval("[1,2,(1,2)]")
[1, 2, (1, 2)]
>>> ast.literal_eval("1f")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/usr/local/lib/python2.7/ast.py", line 37, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    1f
     ^
SyntaxError: unexpected EOF while parsing

If you want to restrict it to 0,1,True,False, I'd do

boolmapping = {'0':False, 'False': False, '1':True, 'True':True}
...
setting = boolmapping.get(setting, setting)

However, this may mistakenly convert an integer that happens to be 1 to True, when really 1 was meant, so you may better map '1' to 1 , not True .

To convert a string to an int if it is one, do

try:
    setting = int(setting)
except ValueError:
    pass

You can simply use:

if setting.value in ["true", "True", 1, "1"]:
    setting.value = True

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM