简体   繁体   中英

How to retrieve a value from an executed string?

I didn't quite know how to word my question as this isn't something one would often do. Here's my situation:

I have a list of values.

Values= ["1","2","3","4"]

I then want to be able to separately access each of the values and combine them into a string with commas in between them. I wrote a bit of code that I want to format a string ('{}'.format())in such a way so that the outcome looks like this: '1,2,3,4'. My code that I have so far (it is also the code structure that I'd prefer to use if possible) is the following:

string = "{}".format(exec(
    "Out= ''\n"
    "for value in Values:\n"
    "    Out+= value + ','\n"
    "Out"))
print(string)

If, within the string that is given as the parameter to the 'exec' function, I write "print(Out)" IE:

string = "{}".format(exec(
    "Out= ''\n"
    "for value in Values:\n"
    "    Out+= value + ','\n"
    "print(Out)"))

Then the program will properly run and print out "1,2,3,4", but it will not store it in 'string' (Which is to be expected)

I therefore thought of adding a function in order to make sure that it can return something. I wrote the following, but as expected it also didn't work. string is still None:

string = "{}".format(exec(
    "def do_stuff():\n"
    "    Out = ''\n"
    "    for value in Values :\n"
    "       Out += value + ','\n"
    "    return Out \n"
    "do_stuff()"))

Now, I do realise that this method of combining strings is nowhere near the preferred way to combine strings, but let me give you some context.

I am making a game in python. There is a Character class and it contains various attributes of various data types (such as dict, list, int, str, float.... as well as some custom ones: AI, Item, ActiveSkill, PassiveSkill, Effect, Weapon, Armour etc...) Now, my plan is to be able to store the game progress in a json tree. For that I started giving each of these entities a method which will convert all of its attributes into json trees stored as strings. That way, when I want to save the game and it comes to the Character, it will sort all of its attributes, but it'll also have to make a call to objects that it's referencing (such as ActiveSkills). For each of ActiveSkills in a list, it'll have to call for their own json syntaxed strings and combine these using commas.

Here's some of my code to help you understand what I want to do:

json += \
    '"ActiveSkills":[{oActiveSkills}],' \
    '"PassiveSkills":[{oPassiveSkills}].' \
    '"Effects":[{oEffects}],'.format(
        oActiveSkills=exec(
            "Skills = ''\n"
            "for skill in self.ActiveSkills:\n"    # ActiveSkills is a list of ActiveSkill objects
            "    Skills+=skill.encode_to_json() + ','\n"
            "return Skills"),
        oPassiveSkills=exec(
            "Skills = ''\n"
            "for skill in self.PassiveSkills:\n"    # PassiveSkills is a list of PassiveSkill objects
            "    Skills+=skill.encode_to_json() + ','\n"
            "return Skills"),
        oEffects=exec(
            "Effects = ''\n"
            "for effect in self.Effects:\n"    # Effects is a list of Effect objects
            "    Effects+=effect.encode_to_json() + ','\n"
            "return Effects"))

I know that this code currently doesn't run, as you can only return from within a function, but I really don't know how to go about it in a quick and easy way.

One solution that I have saved up as a last resort is to just do everything by hand. IE: Have some kind of for loop that creates a string from returned values. Add this string to the json string, after which you will manually open and close with "},{" and make sure that there isn't a "," at the end. Then repeat this for PassiveSkills and Effects also. Finally, close the json string with "}," and add it to the 'json' (string type) variable...

I want to minimise the space taken up by this, and I want this system to be flexible, so that no matter how many skills in a list that you have, you could continue adding more and more of these json strings without changing the code.

To join a list using ',' :

Values = ["1","2","3","4"]
result = ",".join( Values )
print(result)

More info about str.join(iterable) can be found here in the online documentation.

For a better solution to store dictionaries and lists (and, using pickle, objects), you should look at the json and pickle packages in the Python Standard Library.

For example, with json:

import json

mydata = {}
mydata['hello'] = { 'value1':1, 'valuuelist':[1,2,3,4] }

print(json.dumps(mydata))

Output:

{"hello": {"valuuelist": [1, 2, 3, 4], "value1": 1}}

So, don't roll your own encoder, unless you really have to.

For joining each element of a sequence into a string you can use join method.

   L=['1','2','3']
   string=",".join(L)
   print(L)

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