পাইথনে কলিং ফাংশনের মডিউলটির __ নাম__ পান


98

ধরা যাক myapp/foo.py:

def info(msg):
    caller_name = ????
    print '[%s] %s' % (caller_name, msg)

এবং myapp/bar.pyএতে রয়েছে:

import foo
foo.info('Hello') # => [myapp.bar] Hello

আমি এক্ষেত্রে কলিং ফাংশনগুলির মডিউল (যা 'মাই্যাপ.ফু') caller_nameএর __name__বৈশিষ্ট্যে সেট হতে চাই । কিভাবে এই কাজ করা যেতে পারে?


ধরে নিন যে অন্য কোনও এন্ট্রি পয়েন্ট স্ক্রিপ্ট বার.পিকে আহ্বান জানায় .. এবং এভাবে caller_nameহতে পারে না__main__
— শ্রীধর রত্নাকুমার

উত্তর:


125

পরিদর্শন মডিউলটি দেখুন:

inspect.stack() স্ট্যাকের তথ্য ফিরিয়ে দেবে।

কোনও ফাংশনের অভ্যন্তরে, inspect.stack()[1]আপনার কলারের স্ট্যাক ফিরিয়ে দেবে। সেখান থেকে আপনি কলারের ফাংশনটির নাম, মডিউল ইত্যাদি সম্পর্কে আরও তথ্য পেতে পারেন

বিশদ জন্য ডক্স দেখুন:

http://docs.python.org/library/inspect.html

এছাড়াও, ডগ হেলম্যানের তার পিএমওটিডাব্লু সিরিজে পরিদর্শন মডিউলটির একটি সুন্দর রচনাআপ রয়েছে:

http://pymotw.com/2/inspect/index.html#module-inspect

সম্পাদনা: এখানে কিছু কোড যা আপনি যা চান তা করে, আমি মনে করি:

import inspect 

def info(msg):
    frm = inspect.stack()[1]
    mod = inspect.getmodule(frm[0])
    print '[%s] %s' % (mod.__name__, msg)

4
সুতরাং আপনি __name__মডিউলটি ব্যবহার করে এই মডিউলটির বৈশিষ্ট্যটি কীভাবে পাবেন inspect? উদাহরণস্বরূপ, আমি আমার উপরের উদাহরণে কীভাবে ফিরে পাব myapp.foo(না myapp/foo.py)? আমি ইতিমধ্যে এসওতে পোস্ট করার আগে পরিদর্শন মডিউলটি ব্যবহার করার চেষ্টা করেছি।
— শ্রীধর রত্নকুমার

6
সচেতন থাকুন যে এটি আমদানি হুকগুলির সাথে অদ্ভুতভাবে মিথস্ক্রিয়া করবে, আয়রনপথিতে কাজ করবে না এবং জাইথনে বিস্ময়কর উপায়ে আচরণ করতে পারে। আপনি যদি এইভাবে যাদু এড়াতে পারেন তবে এটি সেরা।
— গ্লিফ

4
আরও মনে রাখবেন যে স্ট্যাক ফ্রেমের একটি রেফারেন্স রাখা পাইথনের জিসিকে সঠিকভাবে কাজ করতে বাধা দিতে পারে। সতর্কতা এখানে দেখুন: docs.python.org/library/inspect.html#the-interpreter-stack
— কামিল

6
মনে রাখবেন যে যদি কলার ফাংশনটি সাজানো থাকে (@ ...), আপনাকে inspect.stack()[2]প্রকৃত কলারের জন্য অ্যাক্সেস করতে হবে ।
— আমির আলী আকবরী

এছাড়াও নোট করুন যে আপনি যখন পাইথানস্টলার ব্যবহার করে আপনার পাইথন কোডটি একটি এক্সে রূপায়িত করেন তখন এই যুক্তিটি সঠিকভাবে কাজ করতে ব্যর্থ হয়।
— পানোফিশ

19

একই ধরণের সমস্যার মুখোমুখি হয়ে আমি জানতে পেরেছি যে সিস মডিউল থেকে sys._current_frames () তে অন্তত সুনির্দিষ্ট ব্যবহারের ক্ষেত্রে পরিদর্শন আমদানির প্রয়োজন ছাড়াই আপনাকে সহায়তা করতে পারে এমন আকর্ষণীয় তথ্য রয়েছে।

>>> sys._current_frames()
{4052: <frame object at 0x03200C98>}

তারপরে আপনি f_back ব্যবহার করে "উপরে উঠতে" পারেন:

>>> f = sys._current_frames().values()[0]
>>> # for python3: f = list(sys._current_frames().values())[0]

>>> print f.f_back.f_globals['__file__']
'/base/data/home/apps/apricot/1.6456165165151/caller.py'

>>> print f.f_back.f_globals['__name__']
'__main__'

উপরের মার্ক রডির পরামর্শ অনুসারে ফাইলের নামের জন্য আপনি f.f_back.f_code.co_filename ব্যবহার করতে পারেন। আমি এই পদ্ধতির সীমাবদ্ধতা এবং সতর্কতা সম্পর্কে নিশ্চিত নই (একাধিক থ্রেড সম্ভবত সমস্যা হতে পারে) তবে আমি আমার ক্ষেত্রে এটি ব্যবহারের ইচ্ছা করি।


4
দ্রষ্টব্য: পাইপ স্ট্রোলার ব্যবহার করে এক্সপি করতে সংকলনের পরে পরিদর্শন.স্ট্যাক কোডটি ব্যর্থ হয়, তবে sys._current_frames ওয়ার্কস ফাইন ব্যবহার করে ... সুতরাং এটি আমার পক্ষে পছন্দসই কৌশল।
— প্যানোফিশ

7
আমি মনে করি sys._getframe(1)কল করার পরিবর্তে আগের ফ্রেমটি পাওয়া আরও সহজ sys._current_frames()(বিটিডব্লিউ যা প্রতিটি থ্রেডের জন্য ফ্রেম ম্যাপিং দেয়)।
— হুবলি

আপনাকে হুবলি ধন্যবাদ, আমি এখনও এটি পরীক্ষা করে দেখিনি তবে বহু-থ্রেডেড পরিস্থিতিতে খুব দরকারী বলে মনে হচ্ছে।
— লুই LC

আমি inspect.currentframe()পরিবর্তে ব্যবহার করতে পছন্দ করি sys._current_frames().values()[0]।
— অরণ-ফে

3

আমি এটি করার পরামর্শ দিচ্ছি না, তবে আপনি নিম্নলিখিত পদ্ধতিটি দিয়ে আপনার লক্ষ্যটি অর্জন করতে পারেন:

def caller_name():
    frame=inspect.currentframe()
    frame=frame.f_back.f_back
    code=frame.f_code
    return code.co_filename

তারপরে আপনার বিদ্যমান পদ্ধতিটি নিম্নরূপ আপডেট করুন:

def info(msg):
    caller = caller_name()
    print '[%s] %s' % (caller, msg)

7
ফাইলের __name__
— নামটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.