yet another modifying locals() question

Discussion in 'Python' started by Ed Anuff, Sep 14, 2009.

  1. Ed Anuff

    Ed Anuff Guest

    I know that locals() is not supposed to be modifiable under most
    circumstances, but I'm trying to solve a situation where I'm
    dynamically generating some class attributes and it seemed to be the
    best way, so I tried something out that seems to work but I'm not sure
    that it's kosher:

    >>> def f(l):

    .... l['b'] = 1
    ....
    >>> class A:

    .... f(locals())
    ....
    >>> A.b

    1

    In my code, I'm doing something quite a bit more complex than just
    assigning a single attribute, but this is the simplest use case
    example.

    Is there a reason why this works and is it safe to rely on it or is
    there a better approach? BTW, this works in a program too, it's not
    just an artifact of the command line interpreter globals() = locals()
    thing.

    Thanks

    Ed
     
    Ed Anuff, Sep 14, 2009
    #1
    1. Advertising

  2. On Sun, 13 Sep 2009 18:52:47 -0700, Ed Anuff wrote:

    > I know that locals() is not supposed to be modifiable under most
    > circumstances, but I'm trying to solve a situation where I'm dynamically
    > generating some class attributes and it seemed to be the best way, so I
    > tried something out that seems to work but I'm not sure that it's
    > kosher:


    Given that the docs state not to rely on modifying locals(), I think it
    is safe to say it's NOT kosher. If it works for you, you're lucky, but it
    might stop working in the future.



    >>>> def f(l):

    > ... l['b'] = 1
    > ...
    >>>> class A:

    > ... f(locals())
    > ...
    >>>> A.b

    > 1


    > In my code, I'm doing something quite a bit more complex than just
    > assigning a single attribute, but this is the simplest use case example.


    If you want to dynamically assign attributes after the class is created,
    setattr() is your friend:


    class A:
    pass

    setattr(A, 'b', 1) # set a class attribute


    With full knowledge of the risks of exec'ing untrusted data, you can use
    exec:

    class A:
    exec('b = 1')



    For advanced use, you can look at class decorators and metaclasses.

    def decorator(cls):
    # Add a class attribute b to the cls.
    cls.b = 1
    return cls


    @decorator
    class A:
    pass


    The above @ syntax requires Python 2.6 or better, but in older versions
    you can write:

    class A:
    pass
    A = decorator(A)


    To make it even more dynamic, write a decorator factory:

    def decorator(name):
    def inner(cls):
    setattr(cls, name, 1)
    return cls
    return inner

    class A:
    pass
    A = decorator('b')(A)



    Metaclasses are left as an exercise for the reader.



    --
    Steven
     
    Steven D'Aprano, Sep 14, 2009
    #2
    1. Advertising

  3. Ed Anuff

    Ed Anuff Guest

    On Sep 13, 8:15 pm, Steven D'Aprano
    <> wrote:
    > Metaclasses are left as an exercise for the reader.


    The parent class has a metaclass, which is why I was trying this
    approach instead, since it let me get at the class attributes before
    the metaclass did. Overriding the metaclass looked to be a much more
    messy proposition, but I think I've got that working now. Thanks
     
    Ed Anuff, Sep 14, 2009
    #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. Giles Brown

    Question about "exec in globals, locals"

    Giles Brown, Jul 4, 2003, in forum: Python
    Replies:
    2
    Views:
    378
    Adrien Di Mascio
    Jul 4, 2003
  2. Paul Paterson

    How safe is modifying locals()?

    Paul Paterson, Jul 25, 2003, in forum: Python
    Replies:
    15
    Views:
    510
    Corey Coughlin
    Jul 28, 2003
  3. Faisal Alquaddoomi

    Globals, Locals Dictionaries + Callbacks Question

    Faisal Alquaddoomi, Dec 21, 2005, in forum: Python
    Replies:
    3
    Views:
    384
    Steve Holden
    Dec 22, 2005
  4. Berehem
    Replies:
    4
    Views:
    591
    Lawrence Kirby
    Apr 28, 2005
  5. John [H2O]

    modifying locals

    John [H2O], Oct 30, 2008, in forum: Python
    Replies:
    6
    Views:
    299
    M.-A. Lemburg
    Oct 31, 2008
Loading...

Share This Page