سؤال

وأود أن تحميل .py الملف في وقت التشغيل.هذا .py الملف هو في الأساس config مع الشكل التالي:

var1=value  
var2=value  
predicate_function=func line : <return true or false>  

مرة واحدة يتم تحميل الملف ، أود أن تكون قادرة على الوصول إلى var1, var2 و predicate_function.لكل خط سأتجاوز ذلك إلى المسند وظيفة ، وإذا كان بإرجاع خطأ سوف تجاهله.

في أي حال, أنا لست متأكدا من كيفية تحميل الملف python في وقت التشغيل والوصول إلى المتغيرات.

التوضيح:قد يكون هناك أي عدد من هذه config الملفات التي تحتاج إلى تمرير إلى البرنامج الرئيسي و لن أعرف أسمائهم حتى وقت التشغيل.جوجل تقول لي أنني يجب أن تستخدم __import__.أنا غير متأكد من كيفية بشكل صحيح استخدام هذا الأسلوب ومن ثم الوصول إلى المتغيرات ملف المستوردة.

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

المحلول

وتحتاج فقط لتكون قادرة على تحديد واردات حيوي ومن ثم الحصول بشكل حيوي في المتغيرات.

ويقول

ودعونا ملف التكوين الخاص بك هو bar.py ويشبه هذا:

x = 3
y = 4
def f(x): return (x<4)

وبعد التعليمة البرمجية الخاصة بك ينبغي أن تبدو هذه:

import sys

# somehow modnames should be a list of strings that are the names of config files
#
# you can do this more dynamically depending on what you're doing                                                                                                     
modnames = ['bar']

for modname in modnames:
  exec('import %s' % modname)

for modname in modnames:
  mod = sys.modules[modname]
  for k in mod.__dict__:
    if k[:2] != '__':
      print modname, k, mod.__dict__[k]

وأحصل على هذا الإخراج:

bar f <function f at 0x7f2354eb4cf8>
bar x 3
bar y 4

وبعد ذلك يمكنك على الأقل أن يكون جميع المتغيرات والوظائف. لم أحصل تماما ما تريد من وظائف الأصلية، ولكن ربما يمكنك الحصول على ذلك بنفسك الآن.

نصائح أخرى

وكما هو مكتوب في الثعبان الوثائق الرسمية أو إذا كنت ترغب فقط في استيراد وحدة بالاسم، يمكنك أن تبحث عنه في القاموس sys.modules بعد استخدام __import__.

لنفترض التكوين الخاص بك هو في myproject.mymodule، عليك أن تفعل مثل ما يلي:

module_name = 'myproject.mymodule'

import sys
__import__(module_name)
mymodule = sys.modules[module_name]

# Then you can just access your variables and functions
print mymodule.var1
print mymodule.var2
# etc...

ويمكنك أيضا استخدام قيمة الإرجاع بيان __import__ ولكن سيكون لديك لنفهم تماما كيف يعمل الثعبان مع مساحات ونطاقات .

لوصول وحدة بيثون آخر، <م> استيراده . وقد ورد ذكر execfile من قبل زوجين الناس، وإنما هو فوضوي وخطير. يبعثر execfile مساحة الاسم الخاص بك، وربما حتى خبطة الرمز الذي تقوم بتشغيله. عندما تريد الوصول إلى ملف مصدر بيثون آخر، استخدم العبارة import.

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

إذا وحدة المستوردة في مسار البحث العادي، يمكنك استخدام __import__ .

إذا كنت تحتاج إلى تحميل وحدة من مسار التعسفي في نظام الملفات، واستخدام <لأ href = "http://docs.python.org/library/imp.html؟highlight=__import__#imp.load_module" يختلط = "noreferrer"> imp.load_module .

ومما لا شك فيه للنظر في الآثار الأمنية المترتبة على تحميل التعسفي كود المحددة من قبل المستخدم.

في بيثون 2.*، execfile أعمال (أوصي تمرير القاموس محددة والوصول إلى المتغيرات من هناك - كما الملاحظة في مستندات تقول، execfile لا يمكن أن تؤثر القاموس locals() وظيفة الدعوة ل)

في بيثون 3.*، execfile تمت إزالة، لذلك، بدلا من ذلك:

with open('thefile.py') as f:
  exec(f.read(), somedict)

وأنا كيندا في وقت متأخر إلى الحزب، ولكن أريد أن أقدم جوابا البديلة مع ذلك.

إذا كنت تريد كود استيراد دون التأثير على مساحة حدة العالمي، يمكنك إنشاء وحدة مجهولة (باستخدام types.ModuleType) وتحميل تعليمات برمجية عشوائية في ذلك (باستخدام compile وexec). على سبيل المثال، مثل هذا:

import types

filename = "/path/to/your/file.py"
with open(filename) as fp:
    code = compile(fp.read(), filename, "exec")
config_module = types.ModuleType("<config>")
exec code in config_module.__dict__

وبعد ذلك يمكنك الوصول إلى المتغيرات كما config_module.var1، وج.

إذا كنت تريد أن يكون ملف التكوين التي سيتم تعديلها إلا من قبل المستخدم عند عدم تشغيل البرنامج، فقط استيراده كملف الثعبان العادي

وأي.

وmain.py:

import config
print config.var1

وconfig.py:

var="var12"
var2 = 100.5

ومحاولة وحدة عفريت: http://docs.python.org/library/imp.html

منذ الثعبان النسخة لم يتم ذكر بوضوح, وتجدر الإشارة إلى أن عفريت وحدة تم إيقافها في أحدث إصدارات بيثون لصالح importlib وحدة نمطية. على سبيل المثال هنا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top