PyEval_GetLocals and unreferenced variables

Ned Batchelder ned at nedbatchelder.com
Tue Dec 2 06:04:20 EST 2014


On 12/2/14 4:35 AM, Kasper Peeters wrote:
>>>      def fun():
>>>         cfun_that_creates_q_in_local_scope()
>>>         def fun2():
>>>             cfun_that_wants_to_see_if_q_is_available()
>>>
>>> So the Python side actually doesn't see 'q' directly at all.
>>
>> I think you will need to elaborate.
>
> Ok, here goes (and thanks for listening).
>
> The behaviour of the C side is determined by certain
> settings/preferences. I want these settings to respect the Python
> scope. I could in principle decide to make these settings a proper
> Python object, and ask the user to create one and pass it along at
> every C-function call. Something like
>
>     def fun():
>        settings = Cpp_Options()
>        settings.set_some_flag()
>        cfun(settings, ...)
>        def fun2():
>            settings = Cpp_Options(settings)
>            settings.set_some_other_flag()
>            cfun(settings, ...)
>
> Then Python would automatically take care of the scope of 'settings'.
>
> However, this is difficult for the user to keep track of. So my
> idea was to allow for
>
>    def fun():
>        set_some_flag()
>        cfun(...)
>        def fun2():
>            set_some_other_flag()
>            cfun(...)
>
> I let the C side create a Cpp_Options object on the locals stack
> behind the scenes, and the 'cfun()' function takes it from there
> directly, without requiring the user to pass it. Much easier for the
> user.
>
> This works, but the problem is that the C side does not see the
> settings that were created in fun() when it gets called from fun2(). In
> fun2(), the locals do not contain objects constructed earlier in fun(),
> unless the Python side explicitly refers to them. So adding a line
>
>      settings.do_something()
>
> inside fun2() would work and forces Python to pull the settings object
> created in fun() into scope, but that sort of defeats the purpose.
>

I would use thread locals for this: 
https://docs.python.org/2/library/threading.html#threading.local

They act like global variables, in that they are available implicitly 
without being passed around, but like locals in that two separate 
threads will have different values.

-- 
Ned Batchelder, http://nedbatchelder.com




More information about the Python-list mailing list