পাইথনে বিমূর্ত শ্রেণি এবং ইন্টারফেসের মধ্যে পার্থক্য


উত্তর:


618

আপনি মাঝে মাঝে যা দেখতে পাবেন তা নিম্নলিখিত:

class Abstract1( object ):
    """Some description that tells you it's abstract,
    often listing the methods you're expected to supply."""
    def aMethod( self ):
        raise NotImplementedError( "Should have implemented this" )

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

যখন আপনার হাঁসের টাইপিং থাকে তখন বিমূর্ত এবং ইন্টারফেসের মধ্যে পার্থক্য একটি চুলচেরা জিনিস।

জাভা ইন্টারফেস ব্যবহার করে কারণ এর একাধিক উত্তরাধিকার নেই।

পাইথনের একাধিক উত্তরাধিকার রয়েছে বলে আপনি এটির মতো কিছু দেখতেও পারেন

class SomeAbstraction( object ):
    pass # lots of stuff - but missing something

class Mixin1( object ):
    def something( self ):
        pass # one implementation

class Mixin2( object ):
    def something( self ):
        pass # another

class Concrete1( SomeAbstraction, Mixin1 ):
    pass

class Concrete2( SomeAbstraction, Mixin2 ):
    pass

এটি মিশ্রণগুলির সাথে এক ধরণের অ্যাবস্ট্রাক্ট সুপারক্লাস ব্যবহার করে যা ছিন্নমূল কংক্রিটের সাবক্লাসগুলি তৈরি করে।


5
এস লট, আপনার মানে কি হাঁসের টাইপিংয়ের কারণে হ্যাস-এ (ইন্টারফেস) এবং ইস-এ (উত্তরাধিকার) মধ্যে পার্থক্য নেই?
লরেঞ্জো

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

26
@ এল.ডিলেও - আপনি কি নিশ্চিত যে আপনার একটি বনাম-এর ধারণাটি সঠিক? আমি সাধারণত পার্থক্যটি হ'ল-এ = সদস্য ভেরিয়েবল বনাম হিসাবে-হ'ল- উত্তরাধিকার (পিতামাত্ত শ্রেণি বা ইন্টারফেস) হিসাবে দেখি । জাভাতে তুলনামূলক বা তালিকার কথা চিন্তা করুন; সেগুলি হ'ল একটি সম্পর্ক, তারা ইন্টারফেস বা বিমূর্ত শ্রেণি হোক না কেন।
ডিমো 414

43
NotImplementedError("Class %s doesn't implement aMethod()" % (self.__class__.__name__))আরও তথ্যবহুল ত্রুটির বার্তাটি :)
নট 101

9
@ লরঞ্জো-এর একটি সম্পর্কের উত্তরাধিকার, হাঁসের টাইপিং, ইন্টারফেস এবং বিমূর্ত ক্লাসগুলির সাথে কিছুই করার নেই (চারটিই হ'ল একটি সম্পর্ক।
কার্ল রিখটার

196

পাইথনে অ্যাবস্ট্রাক্ট ক্লাস এবং ইন্টারফেসের মধ্যে পার্থক্য কী?

একটি ইন্টারফেস, কোনও বস্তুর জন্য, সেই অবজেক্টের পদ্ধতি এবং বৈশিষ্ট্যের একটি সেট।

পাইথনে, আমরা একটি ইন্টারফেস সংজ্ঞা এবং প্রয়োগ করতে একটি বিমূর্ত বেস শ্রেণি ব্যবহার করতে পারি।

একটি বিমূর্ত বেস ক্লাস ব্যবহার করে

উদাহরণস্বরূপ, বলুন আমরা collectionsমডিউলটি থেকে একটি বিমূর্ত বেস ক্লাস ব্যবহার করতে চাই :

import collections
class MySet(collections.Set):
    pass

আমরা যদি এটি ব্যবহার করার চেষ্টা করি তবে আমরা একটি পাই TypeErrorকারণ আমাদের তৈরি করা শ্রেণি সেটগুলির প্রত্যাশিত আচরণকে সমর্থন করে না:

>>> MySet()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MySet with abstract methods
__contains__, __iter__, __len__

সুতরাং আমরা এ বাস্তবায়ন প্রয়োজন অন্তত __contains__ , __iter__এবং __len__ডকুমেন্টেশন থেকে এই প্রয়োগের উদাহরণটি ব্যবহার করুন :

class ListBasedSet(collections.Set):
    """Alternate set implementation favoring space over speed
    and not requiring the set elements to be hashable. 
    """
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)
    def __iter__(self):
        return iter(self.elements)
    def __contains__(self, value):
        return value in self.elements
    def __len__(self):
        return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2

বাস্তবায়ন: একটি বিমূর্ত বেস ক্লাস তৈরি করা

প্রাসঙ্গিক পদ্ধতিতে মেটাকগ্লাস সেট করে এবং ডেকরেটার abc.ABCMetaব্যবহার করে আমরা আমাদের নিজস্ব বিমূর্ত বেস ক্লাস তৈরি করতে পারি abc.abstractmethod। মেটাক্লাসটি __abstractmethods__অ্যাট্রিবিউটে সজ্জিত ফাংশনগুলি যুক্ত করা হবে , ততক্ষণ সংজ্ঞা দেওয়া না হওয়া অবধি তড়িঘড়ি আটকাবে ।

import abc

উদাহরণস্বরূপ, "কার্যকর" এমন কিছু হিসাবে সংজ্ঞায়িত করা হয়েছে যা কথায় প্রকাশ করতে পারে। বলুন আমরা পাইথন 2 এ কার্যকরভাবে কার্যকর এমন একটি বিমূর্ত বেস শ্রেণি সংজ্ঞা দিতে চেয়েছিলাম:

class Effable(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')

বা পাইথন 3-এ, মেটাক্লাস ঘোষণার সামান্য পরিবর্তন সহ:

class Effable(object, metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')

এখন যদি আমরা ইন্টারফেসটি বাস্তবায়ন না করে কার্যকর একটি অবজেক্ট তৈরি করার চেষ্টা করি:

class MyEffable(Effable): 
    pass

এবং এটি ইনস্ট্যান্ট করার চেষ্টা করুন:

>>> MyEffable()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyEffable with abstract methods __str__

আমাদের বলা হয় যে আমরা কাজ শেষ করিনি।

এখন আমরা যদি প্রত্যাশিত ইন্টারফেস সরবরাহ করে মেনে চলি:

class MyEffable(Effable): 
    def __str__(self):
        return 'expressable!'

তারপরে আমরা বিমূর্তটি থেকে প্রাপ্ত ক্লাসের কংক্রিট সংস্করণটি ব্যবহার করতে সক্ষম হয়েছি:

>>> me = MyEffable()
>>> print(me)
expressable!

ইতিমধ্যে এই ইন্টারফেসগুলি বাস্তবায়িত ভার্চুয়াল সাবক্লাসেসের মতো আমরা এর সাথে আরও কিছু করতে পারি, তবে আমি মনে করি এটি এই প্রশ্নের আওতার বাইরে। এখানে প্রদর্শিত অন্যান্য পদ্ধতিগুলির ক্ষেত্রে abcমডিউলটি ব্যবহার করে এই পদ্ধতিটি মানিয়ে নিতে হবে ।

উপসংহার

আমরা দেখিয়েছি যে একটি অ্যাবস্ট্রাক্ট বেস ক্লাস তৈরি পাইথনের কাস্টম অবজেক্টের জন্য ইন্টারফেসকে সংজ্ঞায়িত করে।


101

পাইথন> = 2.6 এর অ্যাবস্ট্রাক্ট বেস ক্লাস রয়েছে

অ্যাবস্ট্রাক্ট বেস ক্লাস (সংক্ষেপিত এবিসি) হাঁস-টাইপিংয়ের পরিপূরক যখন ইন্টারফেসগুলি সংজ্ঞায়িত করার উপায় সরবরাহ করে যখন হ্যাশট্রের () এর মতো অন্যান্য কৌশলগুলি আনাড়ি হয়ে থাকে। পাইথন ডেটা স্ট্রাকচার (সংগ্রহ মডিউলে), সংখ্যা (সংখ্যার মডিউলে) এবং স্ট্রিমগুলির (আইও মডিউলে) অনেকগুলি বিল্টিন এবিসি নিয়ে আসে। আপনি এবিসি মডিউলটি দিয়ে নিজের নিজস্ব এবিসি তৈরি করতে পারেন।

রয়েছে Zope ইন্টারফেস মডিউল দেখবেন, যার পাকান মতো zope বাইরে প্রকল্প দ্বারা ব্যবহৃত হয়। আমি এর সাথে সত্যই পরিচিত নই, তবে এখানে একটি উইকি পৃষ্ঠা রয়েছে যা সাহায্য করতে পারে।

সাধারণভাবে, আপনাকে অজগর শ্রেণীর ধারণা বা পাইথনে ইন্টারফেসের প্রয়োজন নেই (সম্পাদিত - বিশদর জন্য এস.লোটের উত্তর দেখুন)।


2
পাইথনে এবিসি ব্যবহার করে আপনি কী অর্জন করবেন?
সিপিল

38

পাইথনের আসলেই কোন ধারণা নেই।

এটি হাঁসের টাইপিং ব্যবহার করে, যা ইন্টারফেসের প্রয়োজনীয়তা সরিয়ে দেয় (কমপক্ষে কম্পিউটারের জন্য :-))

পাইথন <= 2.5: বেস ক্লাসগুলি স্পষ্টতই বিদ্যমান, তবে কোনও পদ্ধতিকে 'খাঁটি ভার্চুয়াল' হিসাবে চিহ্নিত করার কোনও সুস্পষ্ট উপায় নেই, সুতরাং শ্রেণিটি সত্যই বিমূর্ত নয়।

পাইথন> = 2.6: বিমূর্ত বেস ক্লাসগুলি বিদ্যমান ( http://docs.python.org/library/abc.html )। এবং আপনাকে এমন উপায়ে নির্দিষ্ট করতে অনুমতি দেয় যা অবশ্যই সাবক্লাসে প্রয়োগ করা উচিত। আমি সিনট্যাক্সটি বেশি পছন্দ করি না তবে বৈশিষ্ট্যটি এখানে রয়েছে। বেশিরভাগ সময় ক্লায়েন্ট পক্ষ থেকে 'ব্যবহার করে' থেকে হাঁসের টাইপিং ব্যবহার করা ভাল।


3
পাইথন 3.0 বাস্তব বিমূর্ত বেস ক্লাস যুক্ত করে। এগুলি সংগ্রহের মডিউলের পাশাপাশি অন্যান্য জায়গাগুলিতেও ব্যবহৃত হয়। docs.python.org/3.0/library/abc.html
লারা

হাঁসের টাইপিং কেন ইন্টারফেসের প্রয়োজনীয়তা সরিয়ে দেয় সে সম্পর্কে একটি উল্লেখ সহায়ক হবে। হাঁসের টাইপিংয়ের বিষয়টি আমার কাছে স্পষ্ট বলে মনে হচ্ছে না, যা আমি যে কোনও পদ্ধতিতে "ঝুঁক" দেওয়ার ক্ষমতা বা কোনও বস্তুর বৈশিষ্ট্য হিসাবে বুঝতে পেরেছি তার অর্থ এই হবে যে আপনাকে প্রয়োজনীয় আচরণগুলি নির্দিষ্ট করার দরকার নেই (এবং আপনাকে স্মরণ করিয়ে দেওয়ার জন্য সংকলকটি পাবেন) তাদের বাস্তবায়নের জন্য), যা আমি কীভাবে অ্যাবস্ট্রাক বেস বেসগুলি বুঝতে পারি।
রেব কেবিন

এটি হাঁসের টাইপিং কম কম তবে একাধিক উত্তরাধিকারের পক্ষে সমর্থন যা জাভা আঁকানো ইন্টারফেস এবং বিমূর্ত শ্রেণীর মধ্যে কৃত্রিম রেখা সরিয়ে দেয়।
মাসি

35

আরও প্রাথমিক পদ্ধতিতে ব্যাখ্যা করার জন্য: একটি ইন্টারফেস হ'ল খালি মাফিন প্যানের মতো। এটি এমন কোনও শ্রেণীর ফাইল যা পদ্ধতি সংজ্ঞাগুলির একটি সেট সহ কোনও কোড নেই।

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

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


+1 স্বতন্ত্রতার জন্য যেখানে এবিসির নিজস্ব বাস্তবায়ন থাকতে পারে - যা নিজেকে
বহির্মুখী করার

17

সাধারণভাবে, ইন্টারফেসগুলি কেবল সেই ভাষাগুলিতেই ব্যবহৃত হয় যা একক-উত্তরাধিকার শ্রেণির মডেল ব্যবহার করে। এই একক-উত্তরাধিকারী ভাষায়, ইন্টারফেসগুলি সাধারণত ব্যবহৃত হয় যদি কোনও শ্রেণি কোনও নির্দিষ্ট পদ্ধতি বা পদ্ধতির সেট ব্যবহার করতে পারে। এছাড়াও এই একক-উত্তরাধিকারী ভাষাগুলিতে, বিমূর্ত ক্লাসগুলি হয় না কোনও বা ততোধিক পদ্ধতি ছাড়াও শ্রেণিবদ্ধ ভেরিয়েবলগুলি সংজ্ঞায়িত করতে ব্যবহৃত হয় বা একক-উত্তরাধিকারের মডেলটি ব্যবহার করে যে পদ্ধতিগুলির সেট ব্যবহার করতে পারে এমন শ্রেণীর সীমাটি সীমাবদ্ধ করতে ব্যবহার করা হয়।

একাধিক-উত্তরাধিকারের মডেলকে সমর্থন করে এমন ভাষাগুলি কেবল ক্লাস বা বিমূর্ত বেস ক্লাস ব্যবহার করে এবং ইন্টারফেস নয়। পাইথন যেহেতু একাধিক উত্তরাধিকারকে সমর্থন করে তাই এটি ইন্টারফেস ব্যবহার করে না এবং আপনি বেস ক্লাস বা বিমূর্ত বেস ক্লাস ব্যবহার করতে চান।

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


2

বিমূর্ত শ্রেণি ক্লাস যা এক বা একাধিক বিমূর্ত পদ্ধতি ধারণ করে। বিমূর্ত পদ্ধতি সহ, বিমূর্ত শ্রেণিতে স্থিতিশীল, শ্রেণি এবং উদাহরণ পদ্ধতি থাকতে পারে। তবে ইন্টারফেসের ক্ষেত্রে এটির বিমূর্ত পদ্ধতি কেবল অন্য নয়। সুতরাং বিমূর্ত শ্রেণীর উত্তরাধিকারী হওয়া বাধ্যতামূলক নয় তবে ইন্টারফেসের উত্তরাধিকারী হওয়া বাধ্যতামূলক।


1

সম্পূর্ণতার জন্য, আমাদের PEP3119 উল্লেখ করতে হবে যেখানে ABC চালু হয়েছিল এবং ইন্টারফেসের সাথে তুলনা করা হয়েছিল, এবং মূল তালিনের মন্তব্য।

বিমূর্ত শ্রেণি নিখুঁত ইন্টারফেস নয়:

  • উত্তরাধিকার শ্রেণিবিন্যাসের অন্তর্গত
  • পরিবর্তনীয়

তবে আপনি যদি এটি নিজের মতো করে লেখার বিষয়টি বিবেচনা করেন:

def some_function(self):
     raise NotImplementedError()

interface = type(
    'your_interface', (object,),
    {'extra_func': some_function,
     '__slots__': ['extra_func', ...]
     ...
     '__instancecheck__': your_instance_checker,
     '__subclasscheck__': your_subclass_checker
     ...
    }
)

ok, rather as a class
or as a metaclass
and fighting with python to achieve the immutable object
and doing refactoring
...

আপনি বেশ দ্রুত বুঝতে পারবেন যে আপনি অবশেষে অর্জনের জন্য চাকাটি আবিষ্কার করছেন abc.ABCMeta

abc.ABCMeta অনুপস্থিত ইন্টারফেস কার্যকারিতাটির একটি দরকারী সংযোজন হিসাবে প্রস্তাবিত হয়েছিল, এবং অজগর মতো ভাষায় এটি যথেষ্ট ন্যায্য।

অবশ্যই, সংস্করণ 3 রচনাকালীন এটি আরও উন্নত হতে সক্ষম হয়েছিল এবং নতুন সিনট্যাক্স এবং অপরিবর্তনীয় ইন্টারফেস ধারণা যুক্ত করা ...

উপসংহার:

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