Python: Using vars() to assign a string to a variable

前端 未结 6 1852
南笙
南笙 2020-11-27 17:09

I find it very useful to be able to create new variables during runtime and create a dictionary of the results for processing later, i.e. writing to a file:

         


        
相关标签:
6条回答
  • 2020-11-27 17:32

    I can answer number 3: this isn't good programming practice. I don't exactly see what you are trying to accomplish, but I am sure there is a more elegant way of doing it without using locals() (which is the same as vars() according to help(vars) in the interactive Python shell).

    0 讨论(0)
  • 2020-11-27 17:35

    From the help for vars,

    vars(...) vars([object]) -> dictionary

    Without arguments, equivalent to locals().
    With an argument, equivalent to object.__dict__.
    

    You are using it without vars, so let's look at the help for locals()

    locals(...) locals() -> dictionary

    Update and return a dictionary containing the current scope's local
    

    variables.

    So this answers you first two questions. vars() returns a dictionary to the local variables that is indexed by the name of the variable as a string. The scope is local.

    I'm not sure about the third question, but it does seem like kind of a hack which isn't a good sign. I guess if you're careful about using this only in the correct scope you can get by with it.

    0 讨论(0)
  • 2020-11-27 17:39

    Using vars / locals or globals in this way is (a) poor practice and (b) doesn't work in all cases. See Dynamically set local variable for more details. Bottom line: just use dicts -- that's what they're for.

    0 讨论(0)
  • 2020-11-27 17:41

    The pythonic way to create a sequence of variables

    If you want a sequence of variables, create a sequence. Instead of trying to create independent variables like:

    variable0
    variable1
    variable2
    variable3
    

    You should look at creating a list. This is similar to what S.Lott is suggesting (S.Lott usually has good advice), but maps more neatly onto your for loop:

    sequence = []
    for _ in xrange(10):
        sequence.append(function_that_returns_data())
    

    (Notice that we discard the loop variable (_). We're just trying to get 10 passes.)

    Then your data will be available as:

    sequence[0]
    sequence[1]
    sequence[2]
    sequence[3]
    [...]
    sequence[9]
    

    As an added bonus, you can do:

    for datum in sequence:
        process_data(datum)
    

    At first, you may twitch at having your sequence start at 0. You can go through various contortions to have your actual data start at 1, but it's more pain than it's worth. I recommend just getting used to having zero-based lists. Everything is built around them, and they start to feel natural pretty quickly.

    vars() and locals()

    Now, to answer another part of your question. vars() (or locals()) provides low level access to variables created by python. Thus the following two lines are equivalent.

    locals()['x'] = 4
    x = 4
    

    The scope of vars()['x'] is exactly the same as the scope of x. One problem with locals() (or vars()) is that it will let you put stuff in the namespace that you can't get out of the namespace by normal means. So you can do something like this: locals()[4] = 'An integer', but you can't get that back out without using locals again, because the local namespace (as with all python namespaces) is only meant to hold strings.

    >>> x = 5
    >>> dir()
    ['__builtins__', '__doc__', '__name__', 'x']
    >>> locals()[4] = 'An integer'
    >>> dir()
    [4, '__builtins__', '__doc__', '__name__', 'x']
    >>> x
    5
    >>> 4
    4
    >>> locals()[4]
    'An integer'
    

    Note that 4 does not return the same thing as locals()[4]. This can lead to some unexpected, difficult to debug problems. This is one reason to avoid using locals(). Another is that it's generally a lot of complication just to do things that python provides simpler, less error prone ways of doing (like creating a sequence of variables).

    0 讨论(0)
  • 2020-11-27 17:41

    jcdyer explains the concepts very well and Justin Peel clearly states what vars() and locals() do. But a small example always speeds up understanding.

    class Bull(object):
    
        def __init__(self):
            self.x = 1
            self.y = "this"
    
        def __repr__(self):
            return "Bull()"
    
        def test1(self):
            z = 5
            return vars()
    
        def test2(self):
            y = "that"
            return vars(self)
    
        def test3(self):
            return locals()
    
        def test4(self):
            y = 1
            return locals()
    
    if __name__ == "__main__":
        b = Bull()
        print b.test1()
        print b.test2()
        print b.test3()
        print b.test4()
        print vars(b).get("y")
    

    Which results in:

    {'self': Bull(), 'z': 5}
    {'y': 'this', 'x': 1}
    {'self': Bull()}
    {'y': 1, 'self': Bull()}
    this
    
    0 讨论(0)
  • 2020-11-27 17:48

    Do this instead. It's simpler.

    myDict = {}
    for i in range (1,10):
        temp = "variable"+str(i) 
        myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.
    

    That's all you ever need to do.

    The results will be myDict['variable1'] through myDict['variable9']

    You rarely need vars() or locals(). Just stop using them and use ordinary variables and ordinary dictionaries. Try to avoid things you don't understand and stick to the simple, obvious stuff.

    0 讨论(0)
提交回复
热议问题