dynamic setattr

Discussion in 'Python' started by Mariano Di Felice, Jul 27, 2012.

  1. Hi,
    I have a property file (.ini) that has multiple sections and relative keys, as default structure.

    Now, I would like to export from my utility class methods getter and setter.
    I have started as is:

    class Utility:

    keys = {"STANDUP": ["st_key1", "st_key2", "st_key3", "st_key4"],
    "DEFAULT": ["def_key1", "def_key2", "def_key3", "def_key4", "def_key5"]}


    def __init__(self):
    for section, keyList in keys .items():
    for key in keyList:
    setattr(self, "get_%s" % key, self.get_value(section, key))
    setattr(self, "set_%s" % key, lambda value:self.set_value(section, key, value) )

    def get_value(section, key):
    if file_ini.has_option(section, key):
    return lambda: file_ini.get(section, key)
    return lambda: None

    def set_value(section, key, value):
    print "set section: %s - key: %s - value: %s" % (section, key, value)
    if file_ini.has_option(section, key):
    file_ini.set(section , key ,value)


    if __name__ == "__main__":
    utility = Utility()
    print "key2: %s" % utility.get_def_key2() ## -> value return 100
    print "set value 50 to def_key2"
    utility.set_def_key2(50)
    print "new value def_key2: %s" % utility.get_def_key2() ## -> value return 100


    Well, when in code I set value 50 to def_key2, return value of key st_key4 of STANDUP section!!!! Why?
    "set section STANDUP - key st_key4 - value: 200"

    Can anyone help me, please???

    Thx in Advance
    Mariano Di Felice, Jul 27, 2012
    #1
    1. Advertising

  2. On Fri, 27 Jul 2012 05:49:45 -0700, Mariano Di Felice wrote:

    > Hi,
    > I have a property file (.ini) that has multiple sections and relative
    > keys, as default structure.


    Have you looked at Python's standard INI file library?

    http://docs.python.org/library/configparser.html


    > Now, I would like to export from my utility class methods getter and
    > setter. I have started as is:
    >
    > class Utility:
    >
    > keys = {"STANDUP": ["st_key1", "st_key2", "st_key3", "st_key4"],
    > "DEFAULT": ["def_key1", "def_key2", "def_key3",
    > "def_key4", "def_key5"]}


    This defines a *shared* class attribute. As it is attached to the class,
    not an instance, every instance will see the same shared dict.


    > def __init__(self):
    > for section, keyList in keys .items():
    > for key in keyList:


    As given, this is a SyntaxError. Please do not retype your code from
    memory, always COPY AND PASTE your actual code.

    In this case, it is easy to fix the syntax error by fixing the
    indentation. But what other changes have you made by accident?

    Your code:

    def __init__(self):
    for section, keyList in keys .items():

    looks for a *global variable* called keys, *not* the shared class
    attribute Utility.keys. By design, attributes are not in the function
    scope. If you want to access an attribute, whether class or instance, you
    must always refer to them as attributes.


    def __init__(self):
    for section, keyList in self.keys.items(): # this will work


    > setattr(self, "get_%s" % key, self.get_value(section,
    > key))
    > setattr(self, "set_%s" % key, lambda
    > value:self.set_value(section, key, value) )



    What a mess. What is the purpose of this jumble of code?

    My guess is that you are experienced with Java, and you are trying to
    adapt Java idioms and patterns to Python. Before you do this, you should
    read these two articles by a top Python developer who also knows Java
    backwards:

    http://dirtsimple.org/2004/12/python-is-not-java.html
    http://dirtsimple.org/2004/12/java-is-not-python-either.html



    > if __name__ == "__main__":
    > utility = Utility()
    > print "key2: %s" % utility.get_def_key2() ## -> value return 100


    Again, another SyntaxError. This can be fixed. But the next part cannot.

    Except for two comments, 100 does not exist in your sample code. Python
    doesn't magically set values to 100. The code you give cannot possibly
    return 100 since nowhere in your code does it set anything to 100.

    If you actually run the code you provide (after fixing the SyntaxErrors),
    you get this error:

    py> utility = Utility()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 5, in __init__
    NameError: global name 'keys' is not defined


    If you fix that and try again, you get this error:

    py> utility = Utility()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 7, in __init__
    TypeError: get_value() takes exactly 2 arguments (3 given)


    The results you claim you get are not true.


    Please read this page and then try again:

    http://sscce.org/



    --
    Steven
    Steven D'Aprano, Jul 27, 2012
    #2
    1. Advertising

  3. Hi Steven,
    Sorry for inconvenients.
    I've posted "unsyntax" example just typing from here, just for exaplain my problem

    Finally, I don't understand why every set_<key> set value on wrong section/key.
    I think setattr syntax is correct, but it doesn't works!

    About java/python concept, yeah! You all right!
    But I need a conversion class (as Utility) that expose getter/setter of anykeys.

    Thx!

    Il giorno venerdì 27 luglio 2012 15:46:59 UTC+2, Steven D'Aprano ha scritto:
    > On Fri, 27 Jul 2012 05:49:45 -0700, Mariano Di Felice wrote:
    >
    > &gt; Hi,
    > &gt; I have a property file (.ini) that has multiple sections and relative
    > &gt; keys, as default structure.
    >
    > Have you looked at Python's standard INI file library?


    I already use it!

    >
    > http://docs.python.org/library/configparser.html
    >
    >
    > &gt; Now, I would like to export from my utility class methods getter and
    > &gt; setter. I have started as is:
    > &gt;
    > &gt; class Utility:
    > &gt;
    > &gt; keys = {&quot;STANDUP&quot;: [&quot;st_key1&quot;, &quot;st_key2&quot;, &quot;st_key3&quot;, &quot;st_key4&quot;],
    > &gt; &quot;DEFAULT&quot;: [&quot;def_key1&quot;, &quot;def_key2&quot;, &quot;def_key3&quot;,
    > &gt; &quot;def_key4&quot;, &quot;def_key5&quot;]}
    >
    > This defines a *shared* class attribute. As it is attached to the class,
    > not an instance, every instance will see the same shared dict.
    >
    >
    > &gt; def __init__(self):
    > &gt; for section, keyList in keys .items():
    > &gt; for key in keyList:
    >
    > As given, this is a SyntaxError. Please do not retype your code from
    > memory, always COPY AND PASTE your actual code.
    >
    > In this case, it is easy to fix the syntax error by fixing the
    > indentation. But what other changes have you made by accident?
    >
    > Your code:
    >
    > def __init__(self):
    > for section, keyList in keys .items():
    >
    > looks for a *global variable* called keys, *not* the shared class
    > attribute Utility.keys. By design, attributes are not in the function
    > scope. If you want to access an attribute, whether class or instance, you
    > must always refer to them as attributes.
    >
    >
    > def __init__(self):
    > for section, keyList in self.keys.items(): # this will work
    >
    >
    > &gt; setattr(self, &quot;get_%s&quot; % key, self.get_value(section,
    > &gt; key))
    > &gt; setattr(self, &quot;set_%s&quot; % key, lambda
    > &gt; value:self.set_value(section, key, value) )
    >
    >
    > What a mess. What is the purpose of this jumble of code?
    >
    > My guess is that you are experienced with Java, and you are trying to
    > adapt Java idioms and patterns to Python. Before you do this, you should
    > read these two articles by a top Python developer who also knows Java
    > backwards:
    >
    > http://dirtsimple.org/2004/12/python-is-not-java.html
    > http://dirtsimple.org/2004/12/java-is-not-python-either.html
    >
    >
    >
    > &gt; if __name__ == &quot;__main__&quot;:
    > &gt; utility = Utility()
    > &gt; print &quot;key2: %s&quot; % utility.get_def_key2() ## -&gt; value return 100
    >
    > Again, another SyntaxError. This can be fixed. But the next part cannot.
    >
    > Except for two comments, 100 does not exist in your sample code. Python
    > doesn't magically set values to 100. The code you give cannot possibly
    > return 100 since nowhere in your code does it set anything to 100.
    >
    > If you actually run the code you provide (after fixing the SyntaxErrors),
    > you get this error:
    >
    > py&gt; utility = Utility()
    > Traceback (most recent call last):
    > File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
    > File &quot;&lt;stdin&gt;&quot;, line 5, in __init__
    > NameError: global name 'keys' is not defined
    >
    >
    > If you fix that and try again, you get this error:
    >
    > py&gt; utility = Utility()
    > Traceback (most recent call last):
    > File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
    > File &quot;&lt;stdin&gt;&quot;, line 7, in __init__
    > TypeError: get_value() takes exactly 2 arguments (3 given)
    >
    >
    > The results you claim you get are not true.
    >
    >
    > Please read this page and then try again:
    >
    > http://sscce.org/
    >
    >
    >
    > --
    > Steven
    Mariano Di Felice, Jul 27, 2012
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roman Yakovenko

    __slots__, setattr, __metaclass__

    Roman Yakovenko, Jan 12, 2004, in forum: Python
    Replies:
    1
    Views:
    291
    Michele Simionato
    Jan 12, 2004
  2. Gerson Kurz
    Replies:
    4
    Views:
    379
    Larry Bates
    Jun 14, 2004
  3. dataangel

    Using pickle with setattr

    dataangel, Oct 13, 2004, in forum: Python
    Replies:
    0
    Views:
    266
    dataangel
    Oct 13, 2004
  4. dataangel

    Re: Using pickle with setattr

    dataangel, Oct 14, 2004, in forum: Python
    Replies:
    3
    Views:
    312
    dataangel
    Oct 15, 2004
  5. kramb64

    setattr inside a module

    kramb64, Mar 23, 2005, in forum: Python
    Replies:
    5
    Views:
    278
    Jeremy Bowers
    Mar 23, 2005
Loading...

Share This Page