যদি একটি শ্রেণি অন্য শ্রেণীর সাবক্লাস হয় তবে আমি কীভাবে চেক করব (রানটাইমে)?


196

ধরা যাক যে আমার কাছে ক্লাস স্যুট এবং স্যুটটির চারটি সাবক্লাস রয়েছে: হার্ট, স্প্যাড, ডায়মন্ড, ক্লাব।

class Suit:
   ...
class Heart(Suit):
   ...
class Spade(Suit):
   ...
class Diamond(Suit):
   ...
class Club(Suit):
   ...

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

def my_method(suit):
   assert(suit subclass of Suit)
   ...

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


1
@ লিপড: এটি কি সত্যিই পরিষ্কার নয়? আমি সম্ভাব্য চারটি মানগুলি যা my_methodপরামিতি হিসাবে পেতে পারে ঠিক তা বলেছি : "এটি চারটি মানের মধ্যে একটি মাত্র পেতে পারে: হার্ট, কোদাল, ডায়মন্ড, ক্লাব"। এই মানগুলি শ্রেণীর উদাহরণ নয়, শ্রেণীর উদাহরণ নয়। এটি আমার কাছে বেশ স্পষ্ট বলে মনে হচ্ছে, যদিও আমি মনে করি আপনি অস্পষ্টতার বিষয়ে সঠিক বলেছেন কারণ উত্তরগুলি উভয় সম্ভাবনাকেই কভার করে। আপনি যদি এর জন্য আরও স্পষ্ট বাক্য পেয়ে থাকেন তবে প্রশ্ন সম্পাদনা করার জন্য আপনাকে স্বাগত জানাতে হবে। মন্তব্যের জন্য ধন্যবাদ.
snakile

@ স্নাকিল হ্যাঁ এটি অস্পষ্ট। কারও স্ব-প্রকাশের নির্ভুলতার উপর নির্ভর করার কারণে এই বিষয়ে পাতলা বরফ। বহু আগত ব্যক্তি পাইথন-এ-অবজেক্ট-ইন-অবজেক্ট-এ সমস্ত কিছু পেতে পারে না, একটি জিনিস প্রকাশ করতে পারে তবে অন্যটি ভাবতে পারে। এটি একটি বাস্তবতা এবং পবিত্রতা একদিকে রেখে, নতুনদের কাছ থেকে এই আচরণটি আশা করা যথেষ্ট যুক্তিযুক্ত। আপনার খ্যাতি ছেড়ে দেওয়া এখানে আপনার অভিব্যক্তিটি সঠিক কিনা বা আমি "নির্ভুলতার দিক দিয়ে" বলতে পারি তা কেবল প্রত্যক্ষ ইঙ্গিত দেয় । আমি আপনার জ্ঞানটি আমলে নেওয়ার ইচ্ছাটি বুঝতে পেরেছি এবং চির-পুনর্নবীকরণকারী নতুনদের আমলে না নেওয়ার পক্ষে এটি যুক্তিহীন।
n611x007

1
@snakile, এবং জিনিস এটা একটা নামকরণ কনভেনশন যে সঙ্গে এই ধরনের প্যারামিটার নাম সাফিক্স ব্যবহার করতে যুক্তিসঙ্গত হতে পারে যে _class, তাদের মত উপার্জন suit_class। আমি প্রাসঙ্গিক প্রশ্নে এই জাতীয় নামকরণের প্রস্তাব দিয়েছিলাম
n611x007

উদাহরণ কোড চার লাইন যুক্ত করার পরামর্শ দিন my_method(Heart) my_method(Spade)...
বব স্টেইন

যেসব ক্ষেত্রে ভেরিয়েবল পরীক্ষা করা হচ্ছে এটি কোনও শ্রেণীর হওয়ার গ্যারান্টিযুক্ত নয়, আপনি পাইথন 3 এ একটি শর্ত যুক্ত করতে পারেন inspect.isclassবা কেবল ব্যবহার করতে পারেন, এটি কোনও অ-শ্রেণি পাস করা হলে ত্রুটি বাড়িয়ে তুলবে। এই উত্তর দেখুন । আমি নীচের উত্তরে মন্তব্য করতাম তবে এটি কখনও দিনের আলো দেখেনি। isinstance(myvar, type)issubclass
টোটাল হ্যাক

উত্তর:


224

আপনি ব্যবহার করতে পারেন issubclass()এই মত assert issubclass(suit, Suit)


55
"তবে আপনি কেন এমন কাজ করতে চান?" - কারণ আপনার একটি ধারক শ্রেণি রয়েছে যা আপনাকে নিশ্চিত করতে হবে যে এটি একজাতীয় এবং এটি করার একমাত্র উপায় sertোকানো উপরের ধরণটি পরীক্ষা করা?
অ্যাডাম পার্কিন

140
যদি স্ট্যাক ওভারফ্লোতে একটি ধ্রুবক স্থায়ী থাকে তবে এটি হ'ল আইসনস্ট্যান্স বা ইস্যুব্লক্লাস বোঝায় এমন কোনও উত্তর সহ হাঁসের টাইপিং সম্পর্কে বক্তৃতাও থাকবে!
বেন রবার্টস

26
আমার এই নাম্বার টাইপটি কোনও ইমেজ প্রসেসিং অ্যাপ্লিকেশনটির জন্য একটি ভাসা বা কোনও int কিনা তা সনাক্ত করার চেষ্টা করার চেষ্টা করে আমি এই প্রশ্নটি জুড়ে এসেছি। যদি এটি ভাসমান হয়, তবে কনভেনশনটি 0.0 এবং 1.0 এর মধ্যে স্বাভাবিক হতে হবে, যদি এটি পূর্ববর্তী হয় তবে কনভেনশনটি 0 থেকে 255 হয় image শুধু "আপনি কি হাঁস" জিজ্ঞাসা করুন এবং সেই অনুযায়ী আমার ক্রিয়াকলাপকে স্কেল করুন।
ওমেগামান

28
সাবক্লাস টেস্টিং অনেকগুলি, বিশেষত জ্যাঙ্গোর মডেলগুলির ইউনিট টেস্টিংকে আরও সহজ করে তোলে। "পাইথন জাভা নয়" " পাইথন প্রোগ্রামারদের কাঁধে এই জাতীয় চিপ থাকতে হবে কেন?
মাইকেল বেকন

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

47

issubclass(class, classinfo)

উদ্ধৃতাংশ:

এর classসাবক্লাস (প্রত্যক্ষ, পরোক্ষ বা ভার্চুয়াল) হলে সত্যটি প্রত্যাবর্তন করুন classinfo


26

isinstanceআপনার কাছে কোনও উদাহরণ থাকলে বা issubclassক্লাস থাকলে আপনি ব্যবহার করতে পারেন । সাধারণত এটি একটি খারাপ ধারণা ভেবেছিল। সাধারণত পাইথনে আপনি যদি কোনও বস্তু এটি করার চেষ্টা করে কোনও জিনিস সক্ষম করতে সক্ষম হন তবে আপনি কাজ করেন।


আপনি যদি জানতে পারেন যে আপনি এটি দিয়ে এটি করতে পারবেন না? আপনি কি একটি ব্যতিক্রম ধরা এবং অন্য কিছু চেষ্টা?
ভুল ব্যবহারকারীর নাম

2
@ ররংগুজারনেম: হ্যাঁ, এটিই 'পাইথোনিক' উপায়। আমি মনে করি এই প্রথাটির যোগ্যতা রয়েছে, তাই যতক্ষণ না এটি আমার কোড পরিষ্কার রাখে ততক্ষণ আমি এটি অনুসরণ করি। এখানে এই সম্পর্কে একটি ভাল আলোচনা আছে: stackoverflow.com/questions/7604636/…
মাইকেল শ্যাপার

8
@ মিশেল শ্যাপার: আমার বলতে হবে, যদি তা পাই পাইথোনিক উপায়, তবে আমি সত্যই পাইথোনিক পদ্ধতিটিকে ঘৃণা করি। আইএমও, ব্যতিক্রমগুলি নিয়ন্ত্রণ প্রবাহের জন্য কখনও ব্যবহার করা উচিত নয়। যদি আপনি ভাবেন যে কোনও ত্রুটি ঘটতে পারে তবে এর বিরুদ্ধে রক্ষা করুন ... এটি কোনও গোটোর মতো আচরণ করবেন না। আকর্ষণীয় লিঙ্কটি আপনি পোস্ট করেছেন, যদিও
লিবিয়াথনবাদার

@ উপরিউচ্চ00: আপনি যে ধরনের ক্ষেত্রে লঙ্ঘনের কথা বলছেন তার মতো শব্দগুলি 'যতক্ষণ না এটি আমার কোড পরিষ্কার রাখে' like আমি সমস্ত পাইথোনিক রীতিনীতিগুলির অনুরাগী নই, যদিও অনেক লোক ইএএফপি নীতিটি অপব্যবহার করে এবং হার্ড-টু-বগ বাগ তৈরি করে।
মাইকেল শ্যাপার 19

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

21

issubclass(sub, sup)বুলিয়ান ফাংশন ফেরৎ সত্য যদি দেওয়া উপশ্রেণী subপ্রকৃতপক্ষে সুপারক্লাস একটি উপশ্রেণী হয় sup


9
একটি বিভ্রান্ত বক্তৃতা ছাড়া উত্তর +1।
গ্রিংগো সুভেভ

2

issubclass ন্যূনতম চলমান উদাহরণ

কিছু দৃ as়তার সাথে এখানে আরও একটি সম্পূর্ণ উদাহরণ:

#!/usr/bin/env python3

class Base:
    pass

class Derived(Base):
    pass

base = Base()
derived = Derived()

# Basic usage.
assert issubclass(Derived, Base)
assert not issubclass(Base, Derived)

# True for same object.
assert issubclass(Base, Base)

# Cannot use object of class.
try:
    issubclass(derived, Base)
except TypeError:
    pass
else:
    assert False

# Do this instead.
assert isinstance(derived, Base)

গিটহাব উজানের দিকে

পাইথন 3.5.0.2 এ পরীক্ষিত।


1

আপনি বিল্টিন ইস্যুব্লাক্লাস ব্যবহার করতে পারেন। তবে টাইপ চেকিংকে সাধারণত অযৌক্তিক হিসাবে দেখা হয় কারণ আপনি হাঁস-টাইপিং ব্যবহার করতে পারেন।


1

ইস্যুব্লক্লাস ব্যবহার করা লগলিভেলগুলি লেখার একটি পরিষ্কার পদ্ধতির মতো মনে হয়েছিল। এটিকে ব্যবহার করা আপনার কাছে অদ্ভুত লাগছে ... তবে এটি অন্যান্য বিকল্পের চেয়ে পরিষ্কার বলে মনে হচ্ছে।

class Error(object): pass
class Warn(Error): pass
class Info(Warn): pass
class Debug(Info): pass

class Logger():
    LEVEL = Info

    @staticmethod
    def log(text,level):
        if issubclass(Logger.LEVEL,level):
            print(text)
    @staticmethod
    def debug(text):
        Logger.log(text,Debug)   
    @staticmethod
    def info(text):
        Logger.log(text,Info)
    @staticmethod
    def warn(text):
        Logger.log(text,Warn)
    @staticmethod
    def error(text):
        Logger.log(text,Error)

0

পাইথন ডকের মতে , আমরা class.__mro__বৈশিষ্ট্য বা class.mro()পদ্ধতিও ব্যবহার করতে পারি :

class Suit:
    pass
class Heart(Suit):
    pass
class Spade(Suit):
    pass
class Diamond(Suit):
    pass
class Club(Suit):
    pass

>>> Heart.mro()
[<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>]
>>> Heart.__mro__
(<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>)

Suit in Heart.mro()  # True
object in Heart.__mro__  # True
Spade in Heart.mro()  # False

-5
#issubclass(child,parent)

class a:
    pass
class b(a):
    pass
class c(b):
    pass

print(issubclass(c,b))#it returns true

1
কোড-কেবল উত্তরগুলি এসওতে প্রশংসা করা হয় না, আপনার কোডটিতে সর্বদা কিছু ব্যাখ্যামূলক পাঠ্য যুক্ত করা উচিত। তবে, এই উত্তরটি অতিমাত্রায়: এটি পূর্ববর্তী উত্তরে ইতিমধ্যে উল্লিখিত হয়নি এমন কোনও তথ্য যুক্ত করে adds
পিএম 2Ring
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.