কোন বস্তুর প্রকার নির্ধারণ করুন?


1790

কোনও ভেরিয়েবলের তালিকা, অভিধান বা অন্য কিছু কিনা তা নির্ধারণ করার কোনও সহজ উপায় আছে? আমি একটি বস্তু ফিরে পাচ্ছি যা উভয় প্রকারের হতে পারে এবং আমার পার্থক্যটি বলতে সক্ষম হওয়া প্রয়োজন।


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

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

22
@ এস.লট আমি প্রত্যাশা করেছি যে এটি স্পষ্টতই প্রমাণিত হবে যে এটি একটি অনুষঙ্গযুক্ত উদাহরণ; তবুও এটি হাঁসের টাইপিংয়ের একটি প্রধান ব্যর্থতা এবং tryএটির সাহায্য নেই help উদাহরণস্বরূপ, আপনি যদি জানতেন যে কোনও ব্যবহারকারী কোনও স্ট্রিং বা অ্যারেতে যেতে পারে তবে উভয়ই সূচী-সক্ষম, তবে সেই সূচির অর্থ সম্পূর্ণ আলাদা something কেবলমাত্র সে ক্ষেত্রে একটি চেষ্টা-এর উপর নির্ভর করা অপ্রত্যাশিত এবং অদ্ভুত উপায়ে ব্যর্থ হবে। একটি সমাধান হ'ল পৃথক পদ্ধতি তৈরি করা, আরেকটি সামান্য ধরণের চেক যোগ করা। আমি ব্যক্তিগতভাবে একাধিক পদ্ধতির তুলনায় বহুবিধ আচরণ পছন্দ করি যা প্রায় একই কাজ করে ... তবে এটি কেবল আমার :)
রবার্ট পি

22
@ এস.লোট, ইউনিট পরীক্ষার কী হবে? কখনও কখনও আপনি আপনার পরীক্ষাগুলি যাচাই করতে চান যে কোনও ফাংশন সঠিক ধরণের কিছু ফিরিয়ে দিচ্ছে। একটি খুব বাস্তব উদাহরণ হ'ল যখন আপনার ক্লাস কারখানা রয়েছে।
এলিয়ট ক্যামেরন

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

উত্তর:


1974

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


কোনও বস্তুর প্রকৃত প্রকার পেতে, আপনি অন্তর্নির্মিত type()ফাংশনটি ব্যবহার করেন । একমাত্র পরামিতি হিসাবে কোনও বস্তুটি পাস করা হলে সেই বস্তুর প্রকারের বস্তুটি ফিরে আসবে:

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True

এটি অবশ্যই কাস্টম ধরণের জন্যও কাজ করে:

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

মনে রাখবেন যে type() কেবলমাত্র অবজেক্টের তাত্ক্ষণিক ধরণটি ফিরিয়ে দেবে, তবে টাইপ উত্তরাধিকার সম্পর্কে আপনাকে বলতে সক্ষম হবে না।

>>> type(b) is Test1
False

এটি আবরণ করার জন্য, আপনার এটি ব্যবহার করা উচিত isinstance ফাংশনটি । এটি অবশ্যই অন্তর্নির্মিত ধরণের জন্যও কাজ করে:

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance()কোনও বস্তুর প্রকার নিশ্চিত করার জন্য এটি সাধারণত পছন্দসই উপায় কারণ এটি উত্পন্ন প্রকারগুলিও গ্রহণ করবে। সুতরাং আপনি যদি না ব্যবহার করেন তবে প্রকৃতপক্ষে টাইপ অবজেক্টটির (যে কোনও কারণেই) প্রয়োজনisinstance() করা পছন্দ করা হয় type()

এর দ্বিতীয় প্যারামিটারটি isinstance()বেশ কয়েকটি ধরণের ধরণ গ্রহণ করে, তাই এক সাথে একাধিক প্রকারের জন্য পরীক্ষা করা সম্ভব। isinstanceএরপরে সত্যটি ফিরে আসবে, যদি বস্তুটি সেই ধরণের কোনওরকম হয়:

>>> isinstance([], (tuple, list, set))
True

68
প্রকারগুলি সিঙ্গেলন হিসাবে ব্যবহারের isপরিবর্তে এটি আরও স্পষ্ট বলে মনে করি==
জন লা রুই

18
@gnibbler, যেসব ক্ষেত্রে আপনি টাইপচেকিং করছেন (যেটি দিয়ে আপনি শুরু করতে যাচ্ছেন না), isinstanceএটি কোনওভাবেই পছন্দসই ফর্ম, তাই ==বা isব্যবহার করার প্রয়োজন নেই।
মাইক গ্রাহাম

23
@ মাইক গ্রাহাম, এমন সময়গুলি আসে যখন typeসর্বোত্তম উত্তর হয়। বেশিরভাগ সময় যখন isinstanceসর্বোত্তম উত্তর হয় এবং এমন সময় আসে যখন হাঁসের টাইপিং সেরা উত্তর হয়। সমস্ত অপশন সম্পর্কে জানা আপনার পক্ষে গুরুত্বপূর্ণ যাতে আপনি যে পরিস্থিতিটির জন্য আরও উপযুক্ত তা চয়ন করতে পারেন।
জন লা রুই

6
@gnibbler, এটি হতে পারে, যদিও আমি এখনও এমন পরিস্থিতিতে পৌঁছিনি যেখানে এর type(foo) is SomeTypeচেয়ে ভাল হবে isinstance(foo, SomeType)
মাইক গ্রাহাম 16

5
@ পোকে: আমি পিইপি 8 সম্পর্কে সম্পূর্ণরূপে একমত, তবে আপনি এখানে স্ট্রোম্যানকে আক্রমণ করছেন: সোভেনের তর্কের গুরুত্বপূর্ণ অংশটি পিইপি 8 ছিল না, তবে আপনি নিজের ব্যবহারের isinstanceজন্য ব্যবহার করতে পারেন (বিভিন্ন ধরণের অনুসন্ধানের জন্য) এবং পাশাপাশি পাশাপাশি একটি সিনট্যাক্স পরিষ্কার করুন, এতে দুর্দান্ত সুবিধা রয়েছে যে আপনি সাবক্লাসগুলি ক্যাপচার করতে পারেন। কেউ OrderedDictআপনার কোডটি ব্যর্থ হতে ঘৃণা করবে কারণ এটি খাঁটি ডিক্ট গ্রহণ করে।
উড়ন্ত ভেড়া

165

আপনি এটি ব্যবহার করে করতে পারেন type():

>>> a = []
>>> type(a)
<type 'list'>
>>> f = ()
>>> type(f)
<type 'tuple'>

40

এটি try... exceptব্লক ব্যবহার করা আরও পাইথোনিক হতে পারে । এইভাবে, যদি আপনার এমন কোনও শ্রেণি থাকে যা তালিকার মতো বাধা দেয় বা ডিকের মতো কোয়াক্ট করে থাকে তবে এটি এর ধরণের প্রকৃতই নির্বিশেষে এটি সঠিকভাবে আচরণ করবে

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

type(A) is type(B)চেকিংয়ের সাথে অন্য সমস্যাটি হ'ল যদি এটির Aএকটি সাবক্লাস হয় তবে Bএটি falseপ্রোগ্রামিয়ালিটি হিসাবে আপনাকে কখন আসবে তা মূল্যায়ন করে true। যদি কোনও বস্তু একটি তালিকার একটি সাবক্লাস হয় তবে এটি তালিকার মতো কাজ করা উচিত: অন্য উত্তরে উপস্থাপিত ধরণটি পরীক্ষা করা এটি প্রতিরোধ করবে। ( isinstanceতবে কাজ করবে)।


16
হাঁসের টাইপিং আসলে পার্থক্যটি বলার বিষয়ে নয়। এটি একটি সাধারণ ইন্টারফেস ব্যবহার সম্পর্কে।
জাস্টিন ইথিয়র

5
সতর্কতা অবলম্বন করুন - বেশিরভাগ কোডিং শৈলীর গাইডগুলি কোডের স্বাভাবিক নিয়ন্ত্রণ প্রবাহের অংশ হিসাবে ব্যতিক্রম হ্যান্ডলিং ব্যবহার না করার পরামর্শ দেয়, সাধারণত কারণ এটি কোডটি পড়া কঠিন করে তোলে। try... exceptযখন আপনি ত্রুটিগুলি মোকাবেলা করতে চান তবে এটি একটি ভাল সমাধান, তবে ধরণের ভিত্তিতে আচরণের সিদ্ধান্ত নেওয়ার সময় নয়।
রেনস ভ্যান ডের হাইজডেন

34

বস্তুর উদাহরণগুলিতে আপনার এগুলিও রয়েছে:

__class__

অ্যাট্রিবিউট। পাইথন ৩.৩ কনসোল থেকে নেওয়া একটি নমুনা এখানে

>>> str = "str"
>>> str.__class__
<class 'str'>
>>> i = 2
>>> i.__class__
<class 'int'>
>>> class Test():
...     pass
...
>>> a = Test()
>>> a.__class__
<class '__main__.Test'>

সতর্ক থাকুন যে অজগর 3.x এবং নিউ-স্টাইল ক্লাসগুলিতে (পাইথন ২. from থেকে বিকল্পভাবে উপলব্ধ) ক্লাস এবং প্রকারটি একত্রিত করা হয়েছে এবং এটি একসময় অপ্রত্যাশিত ফলাফলের দিকে নিয়ে যেতে পারে। মূলত এই কারণেই আমার পরীক্ষার প্রকারের / ক্লাসগুলির প্রিয় পদ্ধতিটি কার্যকরীভাবে নির্মিত আইসনস্ট্যান্স


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

__class__পাইথন ২.x-তে বেশিরভাগ ক্ষেত্রে ঠিক আছে, পাইথনের একমাত্র অবজেক্টগুলির মধ্যে __class__পুরানো-শৈলীর ক্লাস আফ্রিক রয়েছে। আমি আপনার পাইথন 3 উদ্বেগ বুঝতে পারি না, যাইহোক - এই জাতীয় সংস্করণে, কেবলমাত্র প্রতিটি বস্তুর একটি __class__বৈশিষ্ট্য রয়েছে যা যথাযথ শ্রেণীর দিকে নির্দেশ করে।
অ্যালান ফ্রানজোনি

21

পাইথন অবজেক্টের ধরণ নির্ধারণ করুন

কোন বস্তুর প্রকারটি নির্ধারণ করুন type

>>> obj = object()
>>> type(obj)
<class 'object'>

যদিও এটি কাজ করে, ডাবল আন্ডারস্কোর বৈশিষ্ট্যগুলি এড়িয়ে চলুন __class__- এগুলি শব্দার্থগতভাবে প্রকাশ্য নয় এবং সম্ভবত এই ক্ষেত্রে না হলেও বিল্টিন ফাংশনগুলির সাধারণত ভাল আচরণ হয় have

>>> obj.__class__ # avoid this!
<class 'object'>

টাইপ চেকিং

কোনও ভেরিয়েবলের তালিকা, অভিধান বা অন্য কিছু কিনা তা নির্ধারণ করার কোনও সহজ উপায় আছে? আমি একটি বস্তু ফিরে পাচ্ছি যা উভয় প্রকারের হতে পারে এবং আমার পার্থক্যটি বলতে সক্ষম হওয়া প্রয়োজন।

আচ্ছা এটি একটি আলাদা প্রশ্ন, প্রকার - ব্যবহারটি ব্যবহার করবেন না isinstance:

def foo(obj):
    """given a string with items separated by spaces, 
    or a list or tuple, 
    do something sensible
    """
    if isinstance(obj, str):
        obj = str.split()
    return _foo_handles_only_lists_or_tuples(obj)

এটি এমন কেসটিকে কভার করে যেখানে আপনার ব্যবহারকারী সাবক্ল্যাসিং করে চালাক বা বুদ্ধিমান কিছু করতে পারে str - লিসকভ সাবস্টিটিউশনের নীতি অনুসারে, আপনি আপনার কোডটি ভঙ্গ না করে সাবক্লাস উদাহরণ ব্যবহার করতে সক্ষম হতে চান - এবং এটি isinstanceসমর্থন করে।

বিমূর্ততা ব্যবহার করুন

আরও ভাল, আপনি একটি নির্দিষ্ট বিমূর্ত বেস শ্রেণীর সন্ধান করতে পারেন collectionsবা থেকে numbers:

from collections import Iterable
from numbers import Number

def bar(obj):
    """does something sensible with an iterable of numbers, 
    or just one number
    """
    if isinstance(obj, Number): # make it a 1-tuple
        obj = (obj,)
    if not isinstance(obj, Iterable):
        raise TypeError('obj must be either a number or iterable of numbers')
    return _bar_sensible_with_iterable(obj)

বা জাস্ট স্পষ্টভাবে টাইপ-চেক করবেন না

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

def baz(obj):
    """given an obj, a dict (or anything with an .items method) 
    do something sensible with each key-value pair
    """
    for key, value in obj.items():
        _baz_something_sensible(key, value)

উপসংহার

  • ব্যবহার typeপ্রকৃতপক্ষে একটি উদাহরণের ক্লাস পেতে ।
  • ব্যবহার isinstanceপ্রকৃত সাবক্ল্যাস বা রেজিস্টার্ড বিমূর্ততা স্পষ্টভাবে পরীক্ষা করতে ।
  • এবং কেবল টাইপ-চেকিং এড়িয়ে চলুন যেখানে এটি বোঝা যায়।

স্পষ্টভাবে চেক করার পরিবর্তে সর্বদা try/ উপস্থিত থাকে except
toonarmycaptain

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

13

আপনি ব্যবহার করতে পারেন type()বা isinstance()

>>> type([]) is list
True

সতর্কতা অবলম্বন করুন যে আপনি listএকই নামের বর্তমান স্কোপটিতে একটি ভেরিয়েবল নির্ধারণ করে ক্লোবার বা অন্য কোনও প্রকারের করতে পারেন ।

>>> the_d = {}
>>> t = lambda x: "aight" if type(x) is dict else "NOPE"
>>> t(the_d) 'aight'
>>> dict = "dude."
>>> t(the_d) 'NOPE'

উপরে আমরা দেখতে পাচ্ছি যে dictএকটি স্ট্রিংকে পুনরায় নিয়োগ দেওয়া হয়েছে, সুতরাং পরীক্ষা:

type({}) is dict

... ব্যর্থ।

এটি পেতে এবং type()আরও সতর্কতার সাথে ব্যবহার করতে :

>>> import __builtin__
>>> the_d = {}
>>> type({}) is dict
True
>>> dict =""
>>> type({}) is dict
False
>>> type({}) is __builtin__.dict
True

2
আমি নিশ্চিত নই যে এটির জন্য একটি বিল্টিন ডেটা টাইপের নাম ছায়া দেওয়া খারাপ necessary আপনার dictস্ট্রিং প্রচুর অন্যান্য কোডের জন্যও ব্যর্থ হবে dict([("key1", "value1"), ("key2", "value2")])। এই ধরণের সমস্যার উত্তর হ'ল "তাহলে আর তা করবেন না" । অন্তর্নির্মিত নামগুলির ছায়া নেবেন না এবং জিনিসগুলি সঠিকভাবে কাজ করার আশা করবেন না।
ব্ল্যাকঙ্কহট

3
"আপনারা তা করবেন না" অংশে আমি আপনার সাথে একমত। তবে প্রকৃতপক্ষে কাউকে কিছু না করতে বলার জন্য আপনার কমপক্ষে কেন তা করা উচিত তা ব্যাখ্যা করা উচিত এবং আমি অনুভব করেছি যে এটি কেবল এটি করার একটি প্রাসঙ্গিক সুযোগ ছিল। আমি সতর্ক পদ্ধতিটি কুৎসিত দেখতে এবং বোঝাতে চেয়েছিলাম কেন তারা এটি করতে চান না, তাদের সিদ্ধান্ত নিতে রেখেছিল।
deed02392

টাইপ () ক্লাসিক উদাহরণগুলির জন্য পাইথন ২.x তে প্রত্যাশা অনুযায়ী কাজ করে না।
অ্যালান ফ্রানজনি

5

প্রশ্নগুলি বেশ পুরানো হলেও, আমি নিজেই একটি সঠিক উপায় সন্ধান করতে গিয়ে এই হোঁচট খেয়েছি এবং আমি মনে করি এটি এখনও স্পষ্ট করে বলা দরকার, কমপক্ষে পাইথন ২.x এর জন্য (পাইথন ৩-তে পরীক্ষা করা হয়নি, তবে যেহেতু সমস্যাটি ক্লাসিক ক্লাসগুলির সাথে উত্থিত হয়েছে) যা এই জাতীয় সংস্করণে চলে গেছে, এটি সম্ভবত কোনও ব্যাপার নয়)।

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

type()পদ্ধতির মূল সমস্যাটি হ'ল এটি পুরানো-শৈলীর উদাহরণগুলির সাথে সঠিকভাবে কাজ করে না :

class One:
    pass

class Two:
    pass


o = One()
t = Two()

o_type = type(o)
t_type = type(t)

print "Are o and t instances of the same class?", o_type is t_type

এই স্নিপেট কার্যকর করার ফলে ফল পাওয়া যাবে:

Are o and t instances of the same class? True

কোনটি আমার পক্ষে যুক্তি, বেশিরভাগ লোকেরা প্রত্যাশা করে না।

__class__পদ্ধতির শুদ্ধি সবচেয়ে ঘনিষ্ঠ, কিন্তু এটা হবে এক গুরুত্বপূর্ণ ক্ষেত্রে কাজ না: যখন পাশ-ইন বস্তুর একটি পুরানো ধাঁচের হয় বর্গ (! না একটি দৃষ্টান্ত), যেহেতু যারা বস্তুর যেমন অ্যাট্রিবিউট অভাব।

এটি কোডের সবচেয়ে ছোট স্নিপেট যা আমি ধারাবাহিকভাবে ফ্যাশনে এ জাতীয় বৈধ প্রশ্নটিকে সন্তুষ্ট করতে ভাবতে পারি:

#!/usr/bin/env python
from types import ClassType
#we adopt the null object pattern in the (unlikely) case
#that __class__ is None for some strange reason
_NO_CLASS=object()
def get_object_type(obj):
    obj_type = getattr(obj, "__class__", _NO_CLASS)
    if obj_type is not _NO_CLASS:
        return obj_type
    # AFAIK the only situation where this happens is an old-style class
    obj_type = type(obj)
    if obj_type is not ClassType:
        raise ValueError("Could not determine object '{}' type.".format(obj_type))
    return obj_type

5

আইসনস্ট্যান্স ব্যবহারে সতর্কতা অবলম্বন করুন

isinstance(True, bool)
True
>>> isinstance(True, int)
True

তবে টাইপ করুন

type(True) == bool
True
>>> type(True) == int
False

3

পূর্ববর্তী উত্তরগুলির একপাশে, এটি অস্তিত্বের উল্লেখ করার মতো collections.abcযার মধ্যে বেশ কয়েকটি বিমূর্ত বেস ক্লাস (এবিসি) রয়েছে যা হাঁসের টাইপিংয়ের পরিপূরক।

উদাহরণস্বরূপ, স্পষ্টভাবে যাচাইয়ের পরিবর্তে কোনও কিছুর তালিকা রয়েছে কিনা তা পরীক্ষা করে দেখুন:

isinstance(my_obj, list)

আপনি করতে পারেন, আপনি যদি কেবল সেই জিনিসটি দেখার জন্য আগ্রহী হন যা আপনার অবজেক্টটি আইটেমগুলি পেতে দেয় তবে ব্যবহার করুন collections.abc.Sequence:

from collections.abc import Sequence
isinstance(my_obj, Sequence) 

যদি আপনি অবজেক্টগুলিতে কঠোরভাবে আগ্রহী হন যা আইটেমগুলি স্থাপন, সেট করতে এবং মুছতে অনুমতি দেয় (অর্থাত্‍ পরিবর্তনীয় ক্রম), আপনি বিকল্পটি বেছে নেবেনcollections.abc.MutableSequence

অন্য অনেক ABCs সেখানে সংজ্ঞায়িত করা হয়, Mappingযে বস্তু যেমন মানচিত্র, ব্যবহার করা যেতে পারে জন্য Iterable, Callable, ইত্যাদি ইত্যাদি। এইগুলির একটি সম্পূর্ণ তালিকা ডকুমেন্টেশনে দেখা যাবে collections.abc


1

সাধারণভাবে আপনি শ্রেণীর নামের সাথে অবজেক্ট থেকে একটি স্ট্রিং বের করতে পারেন,

str_class = object.__class__.__name__

এবং তুলনার জন্য এটি ব্যবহার,

if str_class == 'dict':
    # blablabla..
elif str_class == 'customclass':
    # blebleble..

1

ব্যবহারিক পরিবর্তে ব্যবহারিক ক্ষেত্রে typeবা isinstanceআপনি এটিও ব্যবহার করতে পারেন @functools.singledispatchযা জেনেরিক ফাংশন ( বিভিন্ন ধরণের জন্য একই ক্রিয়াকলাপটি কার্যকর করে একাধিক ফাংশন সমন্বিত ফাংশন ) সংজ্ঞায়িত করতে ব্যবহৃত হয় ।

অন্য কথায়, আপনি যখন নিম্নলিখিত কোডগুলির মতো কোড পান তখন এটি ব্যবহার করতে চান:

def do_something(arg):
    if isinstance(arg, int):
        ... # some code specific to processing integers
    if isinstance(arg, str):
        ... # some code specific to processing strings
    if isinstance(arg, list):
        ... # some code specific to processing lists
    ...  # etc

এটি কীভাবে কাজ করে তার একটি ছোট উদাহরণ এখানে দেওয়া হয়েছে:

from functools import singledispatch


@singledispatch
def say_type(arg):
    raise NotImplementedError(f"I don't work with {type(arg)}")


@say_type.register
def _(arg: int):
    print(f"{arg} is an integer")


@say_type.register
def _(arg: bool):
    print(f"{arg} is a boolean")
>>> say_type(0)
0 is an integer
>>> say_type(False)
False is a boolean
>>> say_type(dict())
# long error traceback ending with:
NotImplementedError: I don't work with <class 'dict'>

সংযাত্রী আমরা একবারে বিভিন্ন ধরণের আবরণ করতে বিমূর্ত ক্লাস ব্যবহার করতে পারি :

from collections.abc import Sequence


@say_type.register
def _(arg: Sequence):
    print(f"{arg} is a sequence!")
>>> say_type([0, 1, 2])
[0, 1, 2] is a sequence!
>>> say_type((1, 2, 3))
(1, 2, 3) is a sequence!

0

type()isinstance()বিশেষত এর চেয়ে ভাল সমাধান booleans:

Trueএবং Falseকেবল কীওয়ার্ডগুলি যার অর্থ 1এবং 0পাইথন। সুতরাং,

isinstance(True, int)

এবং

isinstance(False, int)

উভয় ফিরে True। উভয় বুলিয়ান একটি পূর্ণসংখ্যার উদাহরণ। type()তবে, আরও চালাক:

type(True) == int

আয় False

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