এখানে দুটি মূল সমস্যা রয়েছে যা:
__xxx__
পদ্ধতিগুলি কেবল ক্লাসে দেখানো হয়
TypeError: can't set attributes of built-in/extension type 'module'
(1) মানে যে কোনও সমাধানের ক্ষেত্রে কোন মডিউলটি পরীক্ষা করা হচ্ছে তাও ট্র্যাক করে রাখতে হবে, অন্যথায় প্রতিটি মডিউলের ক্ষেত্রে উদাহরণ-প্রতিস্থাপনের আচরণ থাকবে; এবং (2) এর অর্থ হ'ল (1) এমনকি সম্ভব নয় ... কমপক্ষে সরাসরি নয়।
ভাগ্যক্রমে, sys.modules সেখানে কীভাবে যায় তার সম্পর্কে পিক নয়, তবে একটি মোড়ক কাজ করবে তবে কেবল মডিউল অ্যাক্সেসের জন্য (যেমন import somemodule; somemodule.salutation('world')
; একই-মডিউল অ্যাক্সেসের জন্য আপনাকে বিকল্পের শ্রেণি থেকে পদ্ধতিগুলি globals()
ঝাঁকিয়ে পড়তে হবে এবং তাদের সাথে আইয়ারে যুক্ত করতে হবে ) ক্লাসে কাস্টম পদ্ধতি (আমি ব্যবহার করতে পছন্দ করি .export()
) বা জেনেরিক ফাংশন (যেমন ইতিমধ্যে উত্তর হিসাবে তালিকাভুক্ত রয়েছে) দিয়ে একটি জিনিস মনে রাখা উচিত: যদি মোড়ক প্রতিবারই একটি নতুন উদাহরণ তৈরি করে, এবং গ্লোবালগুলি সমাধান না হয়, আপনি সম্পূর্ণ ভিন্ন আচরণের সাথে সমাপ্ত হন Oh ওহ, এবং আপনি একইসাথে উভয়ই ব্যবহার করতে পাবেন না - এটি এক বা অন্যটি।
হালনাগাদ
থেকে গাইডো van Rossum :
আসলে একটি হ্যাক যা মাঝেমধ্যে ব্যবহৃত হয় এবং প্রস্তাবিত হয়: একটি মডিউল পছন্দসই কার্যকারিতা সহ একটি শ্রেণীর সংজ্ঞা দিতে পারে এবং তারপরে শেষে, সেটিকে ক্লাসের উদাহরণ দিয়ে (অথবা ক্লাসের সাথে, যদি আপনি জোর করেন তবে) sys.modules এ নিজেকে প্রতিস্থাপন করতে পারে if , তবে এটি সাধারণত কম দরকারী)। উদাহরণ:
# module foo.py
import sys
class Foo:
def funct1(self, <args>): <code>
def funct2(self, <args>): <code>
sys.modules[__name__] = Foo()
এটি কাজ করে কারণ আমদানি যন্ত্রপাতি সক্রিয়ভাবে এই হ্যাকটিকে সক্ষম করে এবং এর চূড়ান্ত পদক্ষেপটি লোড করার পরে, সিএস.মডিউলগুলি থেকে প্রকৃত মডিউলটিকে টেনে আনে। (এটি কোনও দুর্ঘটনা নয় The হ্যাকটি অনেক আগেই প্রস্তাব করা হয়েছিল এবং আমরা সিদ্ধান্ত নিয়েছি যে আমদানি যন্ত্রপাতিগুলিতে এটি সমর্থন করার জন্য আমাদের যথেষ্ট পছন্দ হয়েছিল))
সুতরাং আপনি যা চান তা অর্জনের প্রতিষ্ঠিত উপায় হ'ল আপনার মডিউলে একটি ক্লাস তৈরি করা এবং মডিউলের শেষ কাজ হিসাবে sys.modules[__name__]
আপনার শ্রেণীর উদাহরণটি প্রতিস্থাপন করুন - এবং এখন আপনি প্রয়োজন হিসাবে __getattr__
/ __setattr__
/ দিয়ে খেলতে পারেন __getattribute__
।
দ্রষ্টব্য 1 : আপনি যদি এই কার্যকারিতাটি ব্যবহার করেন তবে sys.modules
অ্যাসাইনমেন্টটি তৈরি করার পরে মডিউলটিতে থাকা অন্য কিছু যেমন গ্লোবাল, অন্যান্য ফাংশন ইত্যাদি নষ্ট হবে - সুতরাং নিশ্চিত হয়ে নিন যে প্রয়োজনীয় সবকিছু প্রতিস্থাপন শ্রেণীর ভিতরে রয়েছে।
নোট 2 : সমর্থন করার জন্য from module import *
আপনাকে অবশ্যই __all__
শ্রেণিতে সংজ্ঞায়িত করতে হবে ; উদাহরণ স্বরূপ:
class Foo:
def funct1(self, <args>): <code>
def funct2(self, <args>): <code>
__all__ = list(set(vars().keys()) - {'__module__', '__qualname__'})
আপনার পাইথন সংস্করণের উপর নির্ভর করে বাদ পড়ার জন্য অন্যান্য নাম থাকতে পারে __all__
। set()
যদি পাইথন 2 সামঞ্জস্য প্রয়োজন নেই বাদ দেওয়া যেতে পারে।