[Python] كيف يمكنني الحصول على الكود المصدري لوظيفة بايثون؟


Answers

تحتوي وحدة الفحص على طرق لاستعادة شفرة المصدر من كائنات python. على ما يبدو أنه يعمل فقط إذا كان المصدر موجود في ملف بالرغم من ذلك. إذا كان لديكم ذلك أعتقد أنك لن تحتاج إلى الحصول على المصدر من الكائن.

Question

لنفترض أن لدي وظيفة بايثون كما هو موضح أدناه:

def foo(arg1,arg2):
    #do something with args
    a = arg1 + arg2
    return a

يمكنني الحصول على اسم الوظيفة باستخدام foo.func_name . كيف يمكنني برمجيا الحصول على رمز المصدر الخاص به ، كما كتبت أعلاه؟




على الرغم من أنني أتفق بشكل عام على أن inspect هو إجابة جيدة ، إلا أنني لا أوافق على أنه لا يمكنك الحصول على شفرة المصدر للكائنات المحددة في المترجم. إذا كنت تستخدم dill.source.getsource من dill ، يمكنك الحصول على مصدر الوظائف و lambdas ، حتى إذا تم تعريفها بشكل تفاعلي. يمكن أيضًا الحصول على التعليمة البرمجية الخاصة بطرق ووظائف الفئة المحددة أو غير المحددة في curries ... ومع ذلك ، قد لا تتمكن من ترجمة هذا الرمز بدون رمز الكائن المرفق.

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 



أعتقد أن أسماء المتغيرات لا يتم تخزينها في ملفات pyc / pyd / pyo ، لذا لا يمكنك استرجاع خطوط الشفرة الصحيحة إذا لم يكن لديك ملفات مصدر.




للتوسع على إجابة الراوي:

>>> def foo(a):
...    x = 2
...    return x + a

>>> import inspect

>>> inspect.getsource(foo)
u'def foo(a):\n    x = 2\n    return x + a\n'

print inspect.getsource(foo)
def foo(a):
   x = 2
   return x + a

تحرير: كما أشار إلى @ 0sh هذا المثال يعمل باستخدام ipython ولكن ليس python عادي. يجب أن يكون جيدًا في كلاهما ، عند استيراد رمز من ملفات المصدر.




إذا كنت تقوم بتعريف الوظيفة بصرامة وكان تعريفًا قصيرًا نسبيًا ، فسيكون الحل بدون تبعيات هو تعريف الدالة في سلسلة وتعيين eval () للتعبير عن وظيفتك.

على سبيل المثال

funcstring = 'lambda x: x> 5'
func = eval(funcstring)

ثم اختياريًا لتوصيل التعليمة البرمجية الأصلية إلى الوظيفة:

func.source = funcstring



Links