কীভাবে গলিতভাবে পাইথন ক্লাস লোড করা যায়


167

পাইথন শ্রেণীর একটি স্ট্রিং দেওয়া হয়েছে, যেমন my_package.my_module.MyClass, এটি লোড করার সর্বোত্তম উপায় কী?

অন্য কথায় আমি Class.forName()জাভাতে একটি সমতুল্য খুঁজছি , পাইথনে ফাংশন। এটি গুগল অ্যাপ ইঞ্জিনে কাজ করা প্রয়োজন।

সাধারণত এটি এমন একটি ফাংশন হবে যা শ্রেণীর FQN কে স্ট্রিং হিসাবে স্বীকার করে এবং ক্লাসে একটি রেফারেন্স দেয়:

my_class = load_class('my_package.my_module.MyClass')
my_instance = my_class()

আমার পাশাপাশি একটি ভেরিয়েবলের ক্লাস রেফারেন্স নির্ধারণ করতে সক্ষম হতে হবে।
pjesi

1
এই প্রদর্শিত হয় সদৃশ হতে stackoverflow.com/questions/452969/...
cdleary

আপনি ঠিক বলেছেন এটি একটি সদৃশ, এটি
সন্ধানের

1
পাইথনে কখনও এর মতো ক্লাস লোড করার দরকার পড়েনি। মডিউলটি কোথায় তা আপনি জানেন কেন কেবল মডিউলটি লোড করবেন না এবং তারপরে পাইথনের মতো তার ক্লাসগুলি ব্যবহার করুন এটি আপনি এর চেয়ে সহজ সরল
অ্যাডাম স্পেন্স

22
আপনার যদি কখনও এটি করার প্রয়োজন হয় না তবে আপনি এখনও আকর্ষণীয় পর্যাপ্ত প্রোগ্রাম লেখেন নি। চর্চা করতে থাকুন.
জন টাইরি

উত্তর:


194

পাইথন ডকুমেন্টেশন থেকে আপনার এখানে ফাংশনটি চান:

def my_import(name):
    components = name.split('.')
    mod = __import__(components[0])
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

কোনও সরল __import__কাজ না করার কারণ হ'ল প্যাকেজ স্ট্রিংয়ে প্রথম বিন্দুর আগে যে কোনও কিছু আমদানি করা আপনি যে মডিউলটি আমদানি করছেন তার একটি বৈশিষ্ট্য। সুতরাং, এর মতো কিছু কাজ করবে না:

__import__('foo.bar.baz.qux')

উপরের ফাংশনটি আপনাকে এভাবে কল করতে হবে:

my_import('foo.bar.baz.qux')

বা আপনার উদাহরণের ক্ষেত্রে:

klass = my_import('my_package.my_module.my_class')
some_object = klass()

সম্পাদনা : আমি এ থেকে কিছুটা দূরে ছিলাম। আপনি মূলত যা করতে চাইছেন তা হ'ল:

from my_package.my_module import my_class

উপরের ফাংশনটি কেবলমাত্র প্রয়োজনীয় যদি আপনার একটি খালি তালিকা থেকে থাকে। সুতরাং, উপযুক্ত কলটি এরকম হবে:

mod = __import__('my_package.my_module', fromlist=['my_class'])
klass = getattr(mod, 'my_class')

আমি মাই_আইম্পোর্টটি চেষ্টা করেছি ('আমার_প্যাকেজ.আমি_মডিউল.মি_ক্লাস') তবে মাই_ক্লাসের কোনও মডিউল পাওয়া যায়নি, এটি মডিউল নয় এমন একটি শ্রেণি বলে এটি বোঝায়। যাই হোক যদি আমি আমার_আইম্পোর্টে কল করার পরে ক্লাস পেতে গেটটাটার ব্যবহার করতে পারি
pjesi

অদ্ভুত জিনিস. প্রথম বিন্দুর অতীতের সমস্ত কিছুর নাম গ্যাটআটার ব্যবহার করে। কোনও পার্থক্য থাকা উচিত নয়।
জেসন বেকার

ধন্যবাদ আমি মনে করি এটি সেরা উপায়। এখন কেবল 'my_pakcage.my_module.my_class' স্ট্রিংটি মোড_নাম, ক্লাস_নেমে বিভক্ত করার জন্য আমার সবচেয়ে ভাল উপায় প্রয়োজন তবে আমি অনুমান করি যে এটি আমি বের করতে পারি :)
pjesi

2
আমদানির পাইথন ডকুমেন্টেশন (কোডে) ইমপোর্টলিব ব্যবহার করতে বলে। সুতরাং অ্যাডাম স্পেন্সের উত্তর চেকআউট করা উচিত
নাওকো

1
লিঙ্কটি @ ন্যাওকো উল্লেখ করছে: ডকস.পিথন.আর
নোয়েল ইভানস

125

আপনি যদি নিজের রোল করতে না চান তবে pydocমডিউলে একটি ফাংশন উপলব্ধ রয়েছে যা ঠিক এটি করে:

from pydoc import locate
my_class = locate('my_package.my_module.MyClass')

এখানে তালিকাবদ্ধ অন্যদের চেয়ে এই পদ্ধতির সুবিধাটি হ'ল যে কোনও মডিউলের মধ্যে সরাসরি কোনও বস্তু নয়, সরবরাহিত বিন্দু পথে কোনও পাইথন অবজেক্টটি locateপাবেন । যেমন ।my_package.my_module.MyClass.attr

আপনি যদি জানতে আগ্রহী হন যে তাদের রেসিপিটি কী, এখানে ফাংশনটি দেওয়া হচ্ছে:

def locate(path, forceload=0):
    """Locate an object by name or dotted path, importing as necessary."""
    parts = [part for part in split(path, '.') if part]
    module, n = None, 0
    while n < len(parts):
        nextmodule = safeimport(join(parts[:n+1], '.'), forceload)
        if nextmodule: module, n = nextmodule, n + 1
        else: break
    if module:
        object = module
    else:
        object = __builtin__
    for part in parts[n:]:
        try:
            object = getattr(object, part)
        except AttributeError:
            return None
    return object

এটি pydoc.safeimportফাংশন উপর নির্ভর করে । এটির জন্য এখানে ডক্স রয়েছে:

"""Import a module; handle errors; return None if the module isn't found.

If the module *is* found but an exception occurs, it's wrapped in an
ErrorDuringImport exception and reraised.  Unlike __import__, if a
package path is specified, the module at the end of the path is returned,
not the package at the beginning.  If the optional 'forceload' argument
is 1, we reload the module from disk (unless it's a dynamic extension)."""

1
আমি এই উত্তর upvated। বিটিডাব্লু, এখানে কোড রয়েছে যা সেফমিপোর্টও রয়েছে কারণ এটি কেবল পাইডোক আমদানি করাকে বিজোড় বলে মনে হচ্ছে: github.com/python/cpython/blob/…
ব্রায়ানরে

আমি এই উত্তরটিও উন্নত করেছি, এটি সমস্ত প্রাসঙ্গিক উত্তরগুলির মধ্যে সেরা।
সুন্দর ওয়েই

এটি qualnameসঠিকভাবে হ্যান্ডেল করতে সক্ষম হবে বলে মনে হচ্ছে (মডিউল নামস্থানের শীর্ষে বস্তু নয়)।
মিস্টারমিয়াগি

হ্যাঁ, আপনি করতে পারেনlocate('my_package.my_module.MyClass.attr.method.etc')
চাদরিক

109
import importlib

module = importlib.import_module('my_package.my_module')
my_class = getattr(module, 'MyClass')
my_instance = my_class()

9
একবার আপনি মডিউলটি গতিশীলভাবে আমদানি করে নিলে মডিউলটির মাধ্যমে আপনি ক্লাসে অ্যাক্সেস পেতে পারেন
অ্যাডাম স্পেন্স

স্রেফ আমার উত্তরটি আরও সংক্ষিপ্ত হতে সম্পাদিত। পাইথনে কোনও ক্লাস লোড করার এটি সর্বোত্তম উপায়।
অ্যাডাম স্পেন্স

বিবিবি-বেনি এবং স্পেন্স! ;)
dKen

গ্রেট! এটি 2.7 এবং তার থেকে বেশি পর্যন্ত স্ট্যান্ডার্ড লাইব্রেরির অংশ।
Apteryx

এটি কোনও মডিউল / শ্রেণিতে অ্যাক্সেস করার সঠিক উপায়। দস্তাবেজগুলি এখানে এগুলি জানিয়েছে
নোয়েল ইভান্স

29
def import_class(cl):
    d = cl.rfind(".")
    classname = cl[d+1:len(cl)]
    m = __import__(cl[0:d], globals(), locals(), [classname])
    return getattr(m, classname)

5
এটাই পরিষ্কার সমাধান! আপনি ব্যবহার বিবেচনা করতে পারেন:(modulename, classname) = cl.rsplit('.', 2)
vdboor

এটি দুর্দান্ত) আমি বিভিন্ন ব্যবহারের সাথে পুতুল প্যাকেজ তৈরি করেছি, সেখানে শ্রেণিকালও আমদানি করছি। আপনি যদি চান তবে আপনি এটি প্যাকেজটি থেকে ব্যবহার করতে পারেন।
স্ট্যান


আমি গ্লোবাল / স্থানীয়দের পরিবর্তে {pass পাস করতে পেরেছি এবং এটি এখনও ভাল কাজ করে
ভাল্ট্রন

17

আপনি যদি জ্যাঙ্গো ব্যবহার করছেন তবে আপনি এটি ব্যবহার করতে পারেন। হ্যাঁ আমি সচেতন ওপি জ্যাঙ্গোর জন্য জিজ্ঞাসা করিনি, তবে আমি জ্যাঙ্গো সমাধানের সন্ধানে এই প্রশ্নটি পেরিয়েছিলাম, একটিও খুঁজে পাইনি এবং এটি পরবর্তী ছেলে / গ্যালার জন্য এটি রেখেছি যা এটি সন্ধান করে।

# It's available for v1.7+
# https://github.com/django/django/blob/stable/1.7.x/django/utils/module_loading.py
from django.utils.module_loading import import_string

Klass = import_string('path.to.module.Klass')
func = import_string('path.to.module.func')
var = import_string('path.to.module.var')

মনে রাখবেন, আপনি যদি এমন কিছু আমদানি করতে চান যা এর .মতো, ব্যবহার reবা argparseব্যবহার না করে:

re = __import__('re')

5

এখানে আমি খুঁজে পাওয়া কিছু ভাগ হয় __import__এবংimportlib যখন এই সমস্যার সমাধান করার চেষ্টা করছে।

আমি পাইথন ৩.7.৩ ব্যবহার করছি।

আমি যখন dমডিউলে ক্লাসে যাওয়ার চেষ্টা করি a.b.c,

mod = __import__('a.b.c')

modপরিবর্তনশীল শীর্ষ নামস্থান পড়ুন a

ক্লাসে উঠতে dআমার দরকার আছে

mod = getattr(mod, 'b') #mod is now module b
mod = getattr(mod, 'c') #mod is now module c
mod = getattr(mod, 'd') #mod is now class d

যদি আমরা চেষ্টা করি

mod = __import__('a.b.c')
d = getattr(mod, 'd')

আমরা আসলে জন্য চেহারা করার চেষ্টা করছেন a.d

ব্যবহার করার সময় importlib, আমি মনে করি গ্রন্থাগারটি getattrআমাদের জন্য পুনরাবৃত্তি করেছে। সুতরাং, যখন আমরা ব্যবহার করি importlib.import_module, আমরা আসলে গভীরতম মডিউলটিতে একটি হ্যান্ডেল পাই।

mod = importlib.import_module('a.b.c') #mod is module c
d = getattr(mod, 'd') #this is a.b.c.d

1

ঠিক আছে, আমার পক্ষে এটি কাজ করে (আমি পাইথন ২.7 ব্যবহার করছি):

a = __import__('file_to_import', globals(), locals(), ['*'], -1)
b = a.MyClass()

তারপরে, বি 'মাই ক্লাস' শ্রেণীর উদাহরণ


0

আপনি যদি ইতিমধ্যে আপনার পছন্দসই শ্রেণীর উদাহরণ পেয়ে থাকেন তবে আপনি তার শ্রেণীর প্রকারটি বের করতে 'টাইপ' ফাংশনটি ব্যবহার করতে পারেন এবং এটি একটি নতুন উদাহরণ তৈরি করতে ব্যবহার করতে পারেন:

class Something(object):
    def __init__(self, name):
        self.name = name
    def display(self):
        print(self.name)

one = Something("one")
one.display()
cls = type(one)
two = cls("two")
two.display()

-2
module = __import__("my_package/my_module")
the_class = getattr(module, "MyClass")
obj = the_class()

5
নোট করুন যে আমদানি ফাংশনে একটি বাগের কারণে এটি কাজ করে। ফাইল পাথগুলি আমদানি ফাংশনে ব্যবহার করা উচিত নয় এবং অজগর ২.6 এবং তার থেকে উপরে কাজ করবে না: ডকস.পিথন.আর / whatnew / 2.6.html#porting
জেসন বেকার

-2

গুগল অ্যাপ ইঞ্জিনে একটি webapp2ফাংশন বলা হয় import_string। আরও তথ্যের জন্য এখানে দেখুন: https://webapp-improved.appspot.com/api/webapp2.html

সুতরাং,

import webapp2
my_class = webapp2.import_string('my_package.my_module.MyClass')

উদাহরণস্বরূপ এটি webapp2.Routeযেখানে আপনি হ্যান্ডলার বা স্ট্রিং ব্যবহার করতে পারেন সেখানে এটি ব্যবহৃত হয়।

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