سؤال

locals هي وظيفة مدمجة تعرض قاموس القيم المحلية. الوثائق تقول:

تحذير

لا ينبغي تعديل محتويات هذا القاموس؛ قد لا تؤثر التغييرات على قيم المتغيرات المحلية المستخدمة من قبل المترجم.

لسوء الحظ، EXEC لديه نفس المشكلة في Python 3.0. هل هناك أي طريقة جولة هذا؟

حالة الاستخدام

انصح:

@depends("a", "b", "c", "d", "e", "f")
def test():
    put_into_locals(test.dependencies)

يعتمد تخزين السلاسل المقدمة في حججها في القائمة test.dependences. وبعد هذه السلاسل هي مفاتيح في القاموس d. وبعد أود أن أكون قادرا على الكتابة put_into_locals حتى نتمكن من سحب القيم من d ووضعها في السكان المحليين. هل هذا ممكن؟

هل كانت مفيدة؟

المحلول

أنا فقط اختبار exec ويعمل في بيثون 2.6.2

>>> def test():
...     exec "a = 5"
...     print a
...
>>> test()
5

إذا كنت تستخدم Python 3.x، فلا تعمل بعد الآن لأن السكان المحليين محسن كصفيف في وقت التشغيل، بدلا من استخدام القاموس.

عندما يكتشف Python "بيان EXEC"، فسيجبر Python على تبديل التخزين المحلي من القاموس إلى القاموس. ولكن منذ "EXEC" هي وظيفة في Python 3.x، لا يمكن للمترجم أن يجعل هذا التمييز لأن المستخدم قد يكون قد فعل شيء مثل "EXEC = 123".

http://bugs.python.org/issue4831.

لتعديل السكان المحليين في الوظيفة على الطاير غير ممكن دون عواقب عديدة: عادة، لا يتم تخزين وظيفة السكان المحليين في القاموس، ولكن مجموعة، التي يتم تحديد مؤشراتها في وقت الترجمة من اللغات المعروفة. هذا ينص على الأقل مع السكان المحليين الجدد الذي تمت إضافته بواسطة Exec. التحايل exec القديم التحايل على هذا، لأن المترجم عرف أنه إذا حدث exec دون globals / locals args في وظيفة، فإن مساحة الاسم ستكون "غير مكترمة"، أي عدم استخدام صفيف السكان المحليين. نظرا لأن EXEC () هي الآن وظيفة طبيعية، فإن المحول البرمجي لا يعرف ما قد يكون "EXEC" مرتبطا، وبالتالي لا يمكن علاجه هو خصيصا.

نصائح أخرى

يتم تعديل المتغيرات المحلية عن طريق عبارات التخصيص.

إذا كانت لديك مفاتيح قاموس والتي هي سلاسل، فالرجاء عدم جعلها متغيرات محلية - فقط استخدمها ككاتب قاموس مفاتيح.

إذا كنت بالتأكيد يجب لديك المتغيرات المحلية تفعل هذا.

def aFunction( a, b, c, d, e, f ):
    # use a, b, c, d, e and f as local variables

aFunction( **someDictWithKeys_a_b_c_d_e_f )

من شأنها أن تملأ بعض المتغيرات المحلية من قاموسك دون القيام بأي شيء سحرية.

هذا غير ممكن. أعتقد أن هذا هو السماح بتحسينات الأداء في وقت لاحق. PYTHON BYTECODE المراجع السكان المحليين حسب الفهرس، وليس بالاسم؛ إذا كان من الضروري أن يكون السكان المحليين () قديمين، فقد يمنع المترجمين الفوريين من تنفيذ بعض التحسينات، أو جعلها أكثر صعوبة.

أنا شبه متأكد من أنك لن تجد أي واجهة برمجة تطبيقات أساسية تضمن، يمكنك تحرير السكان المحليين مثل هذا، لأنه إذا كان ذلك يمكن أن يفعل ذلك، فإن السكان المحليين () لن يكون لديهم هذا التقييد أيضا.

لا تنس أن جميع السكان المحليين موجودون في وقت الترجمة؛ إذا قمت بالرجوع إلى اسم غير مرتبط بمحلي في وقت الترجمة، فإن المحول البرمجي يفترض أنه عالمي. لا يمكنك "إنشاء" السكان المحليين بعد تجميع.

يرى هذا السؤال لحل واحد ممكن، لكنه اختراق خطير ولا تريد أن تفعل ذلك حقا.

لاحظ أن هناك مشكلة أساسية مع رمز المثال الخاص بك:

@depends("a", "b", "c", "d", "e", "f")
def test():
    put_into_locals(test.dependencies)

"test.dependencies" لا يشير إلى "F.Dependation" حيث f هو الوظيفة الحالية؛ إنه يشير إلى القيمة العالمية الفعلية "اختبار". هذا يعني إذا كنت تستخدم أكثر من ديكور واحد:

@memoize
@depends("a", "b", "c", "d", "e", "f")
def test():
    put_into_locals(test.dependencies)

لن تعمل، لأن "الاختبار" هي وظيفة ملفوفة مذكرات، ولا تعتمد. بيثون حقا يحتاج إلى وسيلة للإشارة إلى "الوظيفة المنفذة حاليا" (والصف).

وأود أن تخزينها في متغير:

refs    = locals()
def set_pets():
    global refs
    animals = ('dog', 'cat', 'fish', 'fox', 'monkey')
    for i in range(len(animals)):
        refs['pet_0%s' % i] = animals[i]

set_pets()
refs['pet_05']='bird'
print(pet_00, pet_02, pet_04, pet_01, pet_03, pet_05 )
>> dog fish monkey cat fox bird

وإذا كنت ترغب في اختبار DCT الخاص بك قبل وضعه في السكان المحليين ():

def set_pets():
    global refs
    sandbox = {}
    animals = ('dog', 'cat', 'fish', 'fox', 'monkey')
    for i in range(len(animals)):
        sandbox['pet_0%s' % i] = animals[i]
    # Test sandboxed dict here
    refs.update( sandbox )

بيثون 3.6.1 على ماوس سييرا

لست متأكدا مما إذا كان عرضة لنفس القيود، ولكن يمكنك الحصول على مرجع مباشر إلى الإطار الحالي (ومن هناك، قاموس المتغيرات المحلية) من خلال وحدة التفتيش:

>>> import inspect
>>> inspect.currentframe().f_locals['foo'] = 'bar'
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'foo', 'inspect']
>>> foo
'bar'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top