আমি কীভাবে পাইথনে ইন্টারফেস প্রয়োগ করব?


182
public interface IInterface
{
    void show();
}

 public class MyClass : IInterface
{

    #region IInterface Members

    public void show()
    {
        Console.WriteLine("Hello World!");
    }

    #endregion
}

আমি কীভাবে এই সি # কোডের পাইথন সমতুল্য প্রয়োগ করব?

class IInterface(object):
    def __init__(self):
        pass

    def show(self):
        raise Exception("NotImplementedException")


class MyClass(IInterface):
   def __init__(self):
       IInterface.__init__(self)

   def show(self):
       print 'Hello World!'

এই একটি ভাল ধারণা?? আপনার উত্তরগুলিতে উদাহরণ দিন।


আপনার ক্ষেত্রে ইন্টারফেস ব্যবহারের উদ্দেশ্য কী হবে?
বান্দি-টি

23
সত্যিই কোন উদ্দেশ্য! আমি কেবল শিখতে চাই যখন অজগরটিতে আপনার ইন্টারফেসের প্রয়োজন তখন কী করবেন?
প্রতীক দেওঘরে

18
raise NotImplementedErrorকি show'র শরীর হওয়া উচিত - কোন জ্ঞান করে তোলে একটি সম্পূর্ণ জেনেরিক বাড়াতে Exceptionযখন পাইথন একটি পুরোপুরি নির্দিষ্ট সংজ্ঞায়িত বিল্ট-ইন এক -!)
অ্যালেক্স Martelli

2
না করা উচিত init IInterface কল প্রদর্শনী () (অথবা ব্যতিক্রম নিজেই বাড়াতে) আপনি একটি বিমূর্ত ইন্টারফেস instantiate করতে পারছি না?
ক্যাটাস্টিক ভয়েজ

1
আমি এর জন্য কিছু ব্যবহার দেখতে পাচ্ছি ... আসুন আমরা বলি যে আপনার একটি অবজেক্ট রয়েছে যা আপনি নিশ্চিত করতে চান একটি নির্দিষ্ট স্বাক্ষর রয়েছে। হাঁসের টাইপিংয়ের মাধ্যমে আপনি গ্যারান্টি দিতে পারবেন না যে বিষয়টি আপনি প্রত্যাশিত স্বাক্ষরটির হয়ে উঠবে। কখনও কখনও গতিশীল টাইপ করা বৈশিষ্ট্যগুলিতে কিছু টাইপিং প্রয়োগ করতে কার্যকর হতে পারে।
প্রাইম বাই ডিজাইন

উত্তর:


150

যেমনটি এখানে অন্যদের দ্বারা উল্লেখ করা হয়েছে:

পাইথনে ইন্টারফেসগুলি প্রয়োজনীয় নয়। এটি কারণ পাইথনের যথাযথ একাধিক উত্তরাধিকার রয়েছে এবং ডাকটিপিংয়েরও অর্থ হল যে জায়গাগুলি আপনাকে অবশ্যই আবশ্যক জাভাতে ইন্টারফেস রাখতে হবে সেগুলি পাইথনে আপনার দরকার নেই।

এটি বলেছিল, ইন্টারফেসের জন্য এখনও বেশ কয়েকটি ব্যবহার রয়েছে। এর মধ্যে কয়েকটি পাইথন ২.6-এ প্রবর্তিত পাইথনস অ্যাবস্ট্রাক্ট বেস ক্লাস দ্বারা আচ্ছাদিত। এগুলি দরকারী, যদি আপনি বেস ক্লাস করতে চান যা তাত্ক্ষণিকভাবে চালু করা যায় না তবে নির্দিষ্ট ইন্টারফেস বা বাস্তবায়নের অংশ সরবরাহ করে।

আরেকটি ব্যবহার হ'ল যদি আপনি কোনওভাবে নির্দিষ্ট করতে চান যে কোনও বস্তু একটি নির্দিষ্ট ইন্টারফেস প্রয়োগ করে এবং আপনি এবিসি এর জন্য সেগুলি থেকে সাবক্ল্যাসিং করেও ব্যবহার করতে পারেন। অন্য উপায়টি হ'ল zope.interface, একটি মডিউল যা জোপ কম্পোনেন্ট আর্কিটেকচারের একটি অংশ, সত্যিই দুর্দান্তভাবে দুর্দান্ত উপাদান কাঠামো। এখানে আপনি ইন্টারফেসগুলি থেকে সাবক্লাস করবেন না, পরিবর্তে একটি ইন্টারফেস বাস্তবায়ন হিসাবে ক্লাসগুলি (বা এমনকি উদাহরণগুলি) চিহ্নিত করুন। এটি কোনও উপাদান রেজিস্ট্রি থেকে উপাদানগুলি অনুসন্ধান করতেও ব্যবহৃত হতে পারে। Supercool!


11
আপনি এই সম্পর্কে বিস্তারিত বলতে পারেন? ১. এইরকম একটি ইন্টারফেস কীভাবে কার্যকর করা যায়? ২. উপাদানগুলি অনুসন্ধান করতে এটি কীভাবে ব্যবহার করা যেতে পারে?
জিওএডেসিক

42
"পাইথনে ইন্টারফেসের প্রয়োজন হয় না when
ব্যাপটিস্ট ক্যান্ডেলিয়ার 18

6
ইন্টারফেসগুলি প্রায়শই কোনও প্রত্যাশিত ফলাফল পেতে / চারপাশে বস্তুগুলি পাস করার সময় সদস্যদের যথার্থতা প্রয়োগ করতে ব্যবহৃত হয়। অজগর এটি বিকল্প হিসাবে সমর্থন করলে এটি দুর্দান্ত হবে। এটি উন্নয়নের সরঞ্জামগুলিকে আরও ভাল বুদ্ধিমানের অনুমতি দেবে
সোল

1
একটি উদাহরণ এই উত্তর ব্যাপকভাবে উন্নত করবে।
বব

3
"এটি কারণ পাইথনের যথাযথ একাধিক উত্তরাধিকার রয়েছে", কে বলেছিলেন ইন্টারফেসগুলি একাধিক উত্তরাধিকারের জন্য?
আদনানমুতলেব

76

অ্যাবস্ট্রাক্ট বেস ক্লাসগুলির জন্য এবিসি মডিউলটি ব্যবহার করা কৌশলটি মনে হচ্ছে।

from abc import ABCMeta, abstractmethod

class IInterface:
    __metaclass__ = ABCMeta

    @classmethod
    def version(self): return "1.0"
    @abstractmethod
    def show(self): raise NotImplementedError

class MyServer(IInterface):
    def show(self):
        print 'Hello, World 2!'

class MyBadServer(object):
    def show(self):
        print 'Damn you, world!'


class MyClient(object):

    def __init__(self, server):
        if not isinstance(server, IInterface): raise Exception('Bad interface')
        if not IInterface.version() == '1.0': raise Exception('Bad revision')

        self._server = server


    def client_show(self):
        self._server.show()


# This call will fail with an exception
try:
    x = MyClient(MyBadServer)
except Exception as exc:
    print 'Failed as it should!'

# This will pass with glory
MyClient(MyServer()).client_show()

11
ইউগঃ, আই.এম.ও. এর ভাষার অংশ হতে হবে বা একেবারেই ব্যবহৃত না হওয়া উচিত তার জন্য কিছু মডিউল প্রয়োজন।
মাইক ডি ক্লার্ক

আপনি কি এটি বলতে না: if not server.version() == '1.0': raise ...? আমি সত্যিই এই লাইন পেতে না। একটি ব্যাখ্যা স্বাগত হবে।
স্ক্যান্ডিক্স

1
নিবন্ধন করুন টাইপিংয়ের জন্য পাইথনের মতো উত্তর; আমি টাইপ হতে চাই একটি প্রকার বলতে চাইলে আমার কোনও মডিউল আমদানি করতে হবে না। এর প্রতিক্রিয়াটি সাধারণত "ওয়েল পাইথন ডায়নামিকভাবে টাইপ করা হয়" তবে এটি অজুহাত নয়। জাভা + গ্রোভি এই সমস্যার সমাধান করে। স্ট্যাটিক স্টাফের জন্য জাভা, ডায়নামিক স্টাফের জন্য গ্রোভি।
সর্বশেষে 21

6
@ মাইকেডে ক্লার্ক, অ্যাবসি মডিউলটি সত্যই পাইথনের অন্তর্নির্মিত। এর মধ্যে কয়েকটি নিদর্শন স্থাপন করা এখন আরও কাজ, কারণ 'মোর পাইথোনিক' হিসাবে বিবেচিত বিকল্প নিদর্শনগুলির কারণে এগুলি পাইথনের মূলত অপ্রয়োজনীয়। বিকাশকারীদের বিশাল সংখ্যাগরিষ্ঠদের পক্ষে এটি যেমনটি আপনি বলেছেন, 'মোটেই ব্যবহৃত হয় না' তা হবে। তবে, স্বীকৃতি স্বীকার করে যে এমন কয়েকটি খুব কুলুঙ্গি ক্ষেত্রে রয়েছে যা সত্যই এই আন্তঃবীক্ষণের ক্ষমতা প্রয়োজন, পাইথন স্রষ্টারা এটি সম্ভব করার জন্য একটি সহজেই ব্যবহারযোগ্য API সরবরাহ করেছিলেন।
ডেভিড কালবার্থ

39

ইন্টারফেস পাইথন 2.7 এবং পাইথন 3.4+ সমর্থন করে।

ইন্টারফেস ইনস্টল করতে আপনাকে করতে হবে

pip install python-interface

উদাহরণ কোড:

from interface import implements, Interface

class MyInterface(Interface):

    def method1(self, x):
        pass

    def method2(self, x, y):
        pass


class MyClass(implements(MyInterface)):

    def method1(self, x):
        return x * 2

    def method2(self, x, y):
        return x + y

7
এই লাইব্রেরির একটি বড় সুবিধা, আইএমএইচও, এটি আপনাকে দেওয়া প্রাথমিক ব্যর্থতা: যদি আপনার ক্লাসটি একটি নির্দিষ্ট ইন্টারফেসটি সঠিকভাবে প্রয়োগ না করে, ক্লাসটি পড়ার সাথে সাথে আপনি একটি ব্যতিক্রম পান - আপনাকে এমনকি এটি ব্যবহার করতে হবে না । পাইথনের নিজস্ব বিমূর্ত বেস ক্লাসের সাথে, আপনি প্রথম যখন নিজের ক্লাসটি ইনস্ট্যান্ট করবেন তখন আপনি ব্যতিক্রম পাবেন, যা পরবর্তী সময়ে হতে পারে।
হান্স

এটি অপ্রয়োজনীয়, এবিসি অনুরূপ, অন্তর্নির্মিত কার্যকারিতা সরবরাহ করে।
ড্যানিয়েল

@ ড্যানিয়েল ক্যাসারেসে কি এবিসি একটি প্রকৃত ইন্টারফেস সরবরাহ করে বা আপনি কি বোঝাতে চাইছেন যে রাষ্ট্র বা বাস্তবায়ন ছাড়াই বিমূর্ত ক্লাসগুলি এবিসি অফার করে এমন সমাধান?
asaf92

36

অ্যাবস্ট্রাক্ট বেস ক্লাসগুলির সাথে ইন্টারফেস প্রয়োগ করা আধুনিক পাইথন 3 এ অনেক সহজ এবং তারা প্লাগ-ইন এক্সটেনশনের ইন্টারফেস চুক্তি হিসাবে একটি উদ্দেশ্য পরিবেশন করে।

ইন্টারফেস / বিমূর্ত বেস শ্রেণি তৈরি করুন:

from abc import ABC, abstractmethod

class AccountingSystem(ABC):

    @abstractmethod
    def create_purchase_invoice(self, purchase):
        pass

    @abstractmethod
    def create_sale_invoice(self, sale):
        log.debug('Creating sale invoice', sale)

একটি সাধারণ সাবক্লাস তৈরি করুন এবং সমস্ত বিমূর্ত পদ্ধতি ওভাররাইড করুন:

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)

উপরের মতো সাবক্লাসে সুস্পষ্টভাবে create_sale_invoice()এটিকে কল করে আপনার পছন্দ মতো বিমূর্ত পদ্ধতিতে সাধারণ প্রয়োগ হতে পারে super()

একটি সাবক্লাস ইনস্ট্যান্টেশন যা সমস্ত বিমূর্ত পদ্ধতি প্রয়োগ করে না:

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice

আপনার সাথে আনুষাঙ্গিক বৈশিষ্ট্যগুলি, স্থিতিশীল এবং শ্রেণি পদ্ধতিগুলির সাথে সম্পর্কিত এনোটেশনগুলি সংযুক্ত করেও থাকতে পারে @abstractmethod

প্লাগ-ভিত্তিক সিস্টেমগুলি বাস্তবায়নের জন্য অ্যাবস্ট্রাক্ট বেস ক্লাসগুলি দুর্দান্ত। কোনও শ্রেণীর সমস্ত আমদানিকৃত সাবক্লাসগুলি এই মাধ্যমে অ্যাক্সেসযোগ্য __subclasses__(), সুতরাং আপনি যদি কোনও প্লাগইন ডিরেক্টরি থেকে সমস্ত ক্লাস লোড করেন importlib.import_module()এবং যদি তারা বেস বর্গটি সাবক্লাস করেন তবে আপনার মাধ্যমে সেগুলিতে সরাসরি অ্যাক্সেস রয়েছে __subclasses__()এবং আপনি নিশ্চিত হতে পারেন যে ইন্টারফেস চুক্তিটি সকলের জন্য প্রয়োগ করা হয়েছে sure তাত্ক্ষণিক সময় তাদের।

AccountingSystemউপরের উদাহরণের জন্য এখানে প্লাগইন লোডিং বাস্তবায়ন রয়েছে :

...
from importlib import import_module

class AccountingSystem(ABC):

    ...
    _instance = None

    @classmethod
    def instance(cls):
        if not cls._instance:
            module_name = settings.ACCOUNTING_SYSTEM_MODULE_NAME
            import_module(module_name)
            subclasses = cls.__subclasses__()
            if len(subclasses) > 1:
                raise InvalidAccountingSystemError('More than one '
                        f'accounting module: {subclasses}')
            if not subclasses or module_name not in str(subclasses[0]):
                raise InvalidAccountingSystemError('Accounting module '
                        f'{module_name} does not exist or does not '
                        'subclass AccountingSystem')
            cls._instance = subclasses[0]()
        return cls._instance

তারপরে আপনি AccountingSystemক্লাসের মাধ্যমে অ্যাকাউন্টিং সিস্টেম প্লাগইন অবজেক্টটি অ্যাক্সেস করতে পারবেন :

>>> accountingsystem = AccountingSystem.instance()

( এই পাইমোটডব্লু -3 পোস্ট দ্বারা অনুপ্রাণিত ।)


প্রশ্ন: "এবিসি" মডিউলটির নাম কী?
সেবাস্তিয়ান নীলসেন

"এবিসি" এর অর্থ "অ্যাবস্ট্রাক্ট বেস ক্লাসগুলি", অফিসিয়াল ডক্স দেখুন
মিঃ

31

পাইথনের ইন্টারফেসগুলির তৃতীয় পক্ষের বাস্তবায়ন রয়েছে (সর্বাধিক জনপ্রিয় জোপের , এটি টুইস্টে ব্যবহৃত হয় ) তবে পাইথন কোডাররা সাধারণত "বিমূর্ত বেস ক্লাস" (এবিসি) হিসাবে পরিচিত সমৃদ্ধ ধারণাটি ব্যবহার করতে পছন্দ করেন যা ইন্টারফেসের সাথে একত্রিত করে সেখানেও কিছু বাস্তবায়ন দিক থাকার সম্ভাবনা। অ্যাবিসিগুলি পাইথন ২. A এবং বিশেষত পিআইপি দেখুন , তবে পাইথনের পূর্ববর্তী সংস্করণগুলিতেও তারা সাধারণত "যাওয়ার পথে" হিসাবে দেখা যায় - কেবল এমন একটি শ্রেণীর সংজ্ঞা দিন যার পদ্ধতিগুলি উত্থাপন করে NotImplementedErrorযাতে সাবক্লাসগুলি হবে বিজ্ঞপ্তিতে তারা এই পদ্ধতিগুলিকে আরও ভালভাবে অগ্রাহ্য করতে চাইবে - -)


3
পাইথনের ইন্টারফেসগুলির তৃতীয় পক্ষের বাস্তবায়ন এর অর্থ কী? আপনি দয়া করে এবিসি ব্যাখ্যা করতে পারেন?
প্রতীক দেওঘরে 23'10

2
ঠিক আছে, আমি এবিসির "ধনী" হওয়ার বিষয়টি নিয়েছি। ;) Zope.interface এমন কিছু জিনিস করতে পারে যা এবিসির পাশাপাশি অন্যান্য উপায়ের মতো পারে না। তবে অন্যথায় আপনি যথারীতি ঠিক আছেন। +1
লেনার্ট রেজেব্রো

1
@ অ্যালফ্রেড: এর অর্থ zope.interface এর মতো মডিউলগুলি স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্ভুক্ত নয়, তবে পাইপি থেকে পাওয়া যায়।
লেনার্ট রেজেব্রো

আমার এখনও অবিসি'র ধারণাটি আঁকতে খুব কঠিন সময় আছে। এবিসির শর্তে কারও পক্ষে twistsmatrix.com/documents/current/core/howto/compferences.html (আইএমএইচও, ইন্টারফেস ধারণার একটি দুর্দান্ত ব্যাখ্যা) পুনরায় লেখা সম্ভব হবে ? এটা কি কোন ধারণা আছে?
মিসাইল

21

এরকম কিছু (আমার চারপাশে পাইথন না থাকায় এটি হয়ত কাজ করবে না):

class IInterface:
    def show(self): raise NotImplementedError

class MyClass(IInterface):
    def show(self): print "Hello World!"

2
__init__(self)কনস্ট্রাক্টর সম্পর্কে আমার কী করা উচিত ?
প্রতীক দেওঘরে 23'10

1
আপনার উপর যেহেতু একটি বিমূর্ত শ্রেণি থেকে কোনও অবজেক্ট তৈরির বিরুদ্ধে কোনও সংকলন-সময় চেক নেই, আপনি কোডিং / সংকলনের সময় কোনও সুরক্ষা পাবেন না। একটা কন্সট্রাকটর উত্তরাধিকারসূত্রে হবে, সুতরাং বস্তুর হবে নির্মিত পেতে, শুধু হতে "খালি"। এটি হ'ল সিদ্ধান্ত নেওয়ার বিষয় যে আপনি এটির পরে এবং ব্যর্থতাগুলি পরে ঘটানোর অনুমতি দিয়ে বা আরও ব্যতিক্রম ছুঁড়ে একই রকম নির্মাতাকে বাস্তবায়নের মাধ্যমে স্পষ্টভাবে প্রোগ্রামটি বন্ধ করে দেওয়া উচিত the
বান্দি-টি

1
এ কারণেই abc.ABCউত্থাপনের চেয়ে আরও ভাল NotImplementedError- একটি abc.ABCসাবক্লাস ইনস্ট্যান্টেশন যা সমস্ত বিমূর্ত পদ্ধতি প্রয়োগ করে না তাড়াতাড়ি ব্যর্থ হয়, তাই আপনি ত্রুটি থেকে রক্ষা পেয়েছেন। ত্রুটিটি কেমন দেখাচ্ছে তার জন্য নীচে আমার উত্তরটি দেখুন।
মিঃ

8

আমার বোধগম্যতা হল যে পাইথনের মতো গতিময় ভাষায় ইন্টারফেসগুলি প্রয়োজনীয় নয়। জাভাতে (বা সি ++ এর অ্যাবস্ট্রাক্ট বেস ক্লাস সহ) ইন্টারফেসগুলি নিশ্চিত করার অর্থ হ'ল আপনি সঠিক পরামিতিটি পাস করছেন, কার্যের সেটটি সম্পাদন করতে সক্ষম।

উদাহরণস্বরূপ আপনার যদি পর্যবেক্ষক এবং পর্যবেক্ষণযোগ্য হয় তবে পর্যবেক্ষণযোগ্য আইওবসভার ইন্টারফেসকে সমর্থন করে এমন অবজেক্ট সাবস্ক্রাইব করতে আগ্রহী যা ফলস্বরূপ notify কর্ম রয়েছে। এটি সংকলনের সময় পরীক্ষা করা হয়।

পাইথনে, compile timeরানটাইমের সময় এবং পদ্ধতি দেখার জন্য কোনও জিনিস নেই । তদ্ব্যতীত, কেউ __getattr __ () বা __getattribute __ () যাদু পদ্ধতিগুলির সাহায্যে লুকাকে ওভাররাইড করতে পারে। অন্য কথায়, আপনি পর্যবেক্ষক হিসাবে, যে কোনও বস্তু যা অ্যাক্সেসের জন্য কলযোগ্য ফিরে আসতে পারে তা পাস করতে পারেনnotify বৈশিষ্ট্যে

এটি আমাকে উপসংহারে নিয়ে যায়, পাইথনে ইন্টারফেসের উপস্থিতি রয়েছে - এটি কেবল তাদের প্রয়োগকারী মুহূর্তে স্থগিত করা হয় যেখানে তারা প্রকৃতপক্ষে ব্যবহৃত হয়

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