পাইথনে কোনও বস্তুর কোনও বৈশিষ্ট্য রয়েছে কিনা তা কীভাবে জানবেন


1630

পাইথনে কি কোনও উপায়ে কিছু বৈশিষ্ট্য আছে কিনা তা নির্ধারণ করার উপায় আছে? উদাহরণ স্বরূপ:

>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'

আপনি কীভাবে বলতে পারেন aযে propertyএটির আগে এটির বৈশিষ্ট্য আছে কিনা?

উত্তর:


2334

চেষ্টা করুন hasattr():

if hasattr(a, 'property'):
    a.property

সম্পাদনা: নীচে জুইটারলিন্ডের উত্তর দেখুন, কে ক্ষমা চাওয়ার বিষয়ে ভাল পরামর্শ দেয়! খুব পাইথোনিক অ্যাপ্রোচ!

পাইথনের সাধারণ অনুশীলনটি হ'ল, যদি সম্পত্তিটি বেশিরভাগ সময় সেখানে থাকার সম্ভাবনা থাকে তবে কেবল এটি কল করুন এবং হয় ব্যতিক্রমটিকে প্রচার করতে দিন, বা ব্লক ব্যতীত চেষ্টা করে ফাঁদে ফেলুন। এটি সম্ভবত তুলনায় দ্রুত হবে hasattr। সম্পত্তিটি বেশিরভাগ সময় সেখানে না থাকার সম্ভাবনা থাকলে বা আপনি নিশ্চিত নন, hasattrবারবার ব্যতিক্রম ব্লকের মধ্যে পড়ার চেয়ে সম্ভবত সম্ভবত ব্যবহারটি দ্রুত হবে।


19
নেমস্পেসেও ফাংশনগুলি খতিয়ে দেখার জন্য কাজ করছে বলে মনে হয়, যেমন: import string hasattr(string, "lower")
রিভিয়রা

15
hasattrtry/ / ব্যবহার করার মতোই except AttributeErrorহ্যাশট্রারের ডাস্ট্রিং (পাইথন ২.7-এ) বলে যে এটি গ্যাটট্রা হ্যান্ড ক্যাচ ব্যতিক্রম ব্যবহার করে।
জেফ ট্রেটনার

8
@JeffTratner: hasattrদুর্ভাগ্যবশত নয় ঠিক একটি হিসাবে একই try: ... except AttributeError:যেহেতু পাইথন 2.x মধ্যে hasattrহবে সব ব্যতিক্রম ধরা । দয়া করে আমার উত্তরটি উদাহরণ এবং একটি সাধারণ কাজের জন্য দেখুন।
মার্টিন গিসলার

1
@ মার্টিনগিজলার ভাল পয়েন্ট - এটি সমস্ত ব্যতিক্রম ধরায় যেমনটি হয় তেমন এক নয়। কোন সংস্করণটি আরও সঠিক তা নিশ্চিত নন - আপনি যে অনুমানের অধীনে কাজ করছেন এবং আপনার ফাংশনটি কে ডেকে নিচ্ছেন তা নির্ভর করে নির্ভর করে। স্পষ্ট করার জন্য ধন্যবাদ।
জেফ ট্রেটনার

2
hasattrআপনি যদি কোনও বোধগম্য হন তবে এটিও উচ্চতর পছন্দ, যেমন[a.property for a in list_of_as if hasattr(a, "property")]
রাফায়েল মার্টিনস

631

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

ইএএফপি বনাম এলবিওয়াইএল (পুনরায় ছিল: এখনও অবধি কিছুটা হতাশ)
ইএএফপি বনাম এলবিওয়াইএল @ কোডটি পাইথনিস্টার মতো: আইডোমেটিক পাইথন

অর্থাৎ,

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... এটিকে অগ্রাধিকার দেওয়া হয়:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

257
তবে আপনি কীভাবে পরীক্ষা করতে পারেন যে এটি a.property ছিল যা AttributeError সৃষ্টি করেছিল, এবং doStuff () তে কিছু নয়? মনে হচ্ছে আপনি করবেন না। আমি মনে করি ক্ষমা চাওয়া সত্যই সহজ, তবে অনেক সময় এটিও ভুল।
jpalecek

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

74
@ ই 5: আপনার এক্ষেত্রে ন্যায্য পয়েন্ট রয়েছে তবে অনেক ক্ষেত্রে ইএএফপি হ'ল একমাত্র সঠিক বিকল্প। উদাহরণস্বরূপ, আপনি যদি কোনও ফাইলের অস্তিত্ব পরীক্ষা করেন এবং তারপরে এটি খোলেন তবে এটি অবশ্যই উপস্থিত থাকবে বলে আশা করে আপনার কোডটি ভুল is ফাইলটি মুছে ফেলা হতে পারে বা চেক এবং ব্যবহারের মধ্যে নাম পরিবর্তন করা যেতে পারে। একে টেকটিও ত্রুটি বলা হয় (সময়-ব্যবহারের-সময়-চেক-টু-অফ-ব্যবহার) এবং ক্র্যাশগুলি ঘটানো ছাড়াও সুরক্ষা দুর্বলতার উত্স হতে পারে।
সর্বোচ্চ

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

64
সর্বাধিক অস্পষ্টতার অভিযোগগুলির বেশিরভাগই কেবল নমুনা কোডটি সুসংগতভাবে কাঠামোগত না হওয়ার কারণে। এর অভ্যন্তরের একমাত্র জিনিসটি try:চেষ্টা করা বৈশিষ্ট্য অ্যাক্সেস হওয়া উচিত; doStuffপাশাপাশি কার্য সম্পাদনকে মোড়ানোর কোনও কারণ নেই । অস্পষ্টতার জন্য এখনও কিছু সম্ভাবনা রয়েছে যদিও: যদি propertyএকটি সরল বৈশিষ্ট্যের পরিবর্তে গণিত সম্পত্তি হয় তবে এর বাস্তবায়ন AttributeErrorঅভ্যন্তরীণভাবে বাড়তে পারে । এ কারণেই প্রায় সমস্ত বাস্তব পরিস্থিতিতে এরকম getattrহয় hasattrবা ধরা ভাল AttributeError
কার্ল মায়ার

483

আপনি ব্যবহার করতে hasattr()বা ধরতে AttributeErrorপারেন, তবে আপনি যদি সত্যিই সেখানে ডিফল্টর সাথে বৈশিষ্ট্যের মানটি চান না, তবে সর্বোত্তম বিকল্পটি কেবলমাত্র ব্যবহারের জন্য getattr():

getattr(a, 'property', 'default value')

14
এটি পূর্বোক্ত উভয় সমস্যার সমাধান করে: ক) সম্ভাব্য অ্যাট্রিবিউটরারের উত্সের অস্পষ্টতা, খ) ইএএফপি পদ্ধতির সংরক্ষণ করা।
পিটার এম এলিয়াস

6
এটি কোডের 25% লাইন। অবশ্যই এটি সেরা সমাধান হতে হবে।
ফতুহোকু

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

41

আমি মনে করি আপনি যা খুঁজছেন তা হ'ল তাড়াতাড়ি । যাইহোক, আপনি পাইথনের বৈশিষ্ট্যগুলি সনাক্ত করতে চাইলে আমি এরকম কিছু সুপারিশ করব -

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

এখানে অসুবিধাটি হ'ল বৈশিষ্ট্য __get__কোডে বৈশিষ্ট্য ত্রুটিগুলিও ধরা পড়ে।

অন্যথায়, না-

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

দস্তাবেজ: http://docs.python.org/library/funitions.html
সতর্কতা:
আমার প্রস্তাবনার কারণ হ্যাশট্র্টার বৈশিষ্ট্যগুলি সনাক্ত করে না।
লিঙ্ক: http://mail.python.org/pipermail/python-dev/2005- ডিসেম্বার / 058498.html


সুতরাং, আপনার পরামর্শটি কি আপনি বিল্ট ইন না - এটি বাস্তবায়ন করুন!
সাইলেন্টগোস্ট

ঠিক আছে, ঠিক নয়, বিল্ট-ইন আইএফএফ ব্যবহার করবেন না যা আপনি বৈশিষ্ট্যগুলি সনাক্ত করতে চান। অন্যথায় hasattr পুরোপুরি ভাল।
ব্যাটব্র্যাট

3
hasattrসাধারণভাবে বৈশিষ্ট্য সনাক্ত করে fine এটি কেবল এটি- propertyমোড়ক ফাংশনটিতে ব্যতিক্রম বাড়াতে আচরণ করে যার অর্থ এই জাতীয় কোনও বৈশিষ্ট্য নেই; লিঙ্কযুক্ত পাইথন মেলিং তালিকা পোস্টটি এমন একটি সম্পত্তি সম্পর্কে যা আপনি যখন এটি অ্যাক্সেস করার চেষ্টা করেন তখন ব্যতিক্রম করে। সমস্ত ব্যবহারিক উদ্দেশ্যে, বলেন বৈশিষ্ট্যটির অস্তিত্ব নেই, কারণ এটি কখনই কোনও মান তৈরি করে না। এছাড়াও, hasattrকেবল পাই 3.1 এবং এর আগের ক্ষেত্রে ব্যতিক্রমগুলি দমন করে; 3.2+ এ এটি কেবল দমন করে ( Falseপ্রত্যাবর্তনের পরিবর্তে ) AttributeError
শ্যাডোর্যাঞ্জার

32

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

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

2
ভাল hasattr আসলে অনুকূলিত হতে পারে । পিপির সাথে ডিম।
ওডিনহো - ভেলমন্ট

6
+1 টি। এই এমনকি নিরাপদ ব্যবহার না করে hasattrযখন SomeClassওভাররাইড __getattr__থেকে hasattrফেলবো সব পাইথন 2.x ইন ব্যতিক্রম শুধু না AttributeErrorমনে হচ্ছে আপনি আশা করবে। এটি পাইথন ৩.২ এ স্থির করা হয়েছিল - দয়া করে একটি সাধারণ কাজের জন্য আমার অন্যান্য উত্তর দেখুন ।
মার্টিন গিসলার

24

আমি এড়াতে পরামর্শ দিতে চাই:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

@ Jpalecek ব্যবহারকারী এটি উল্লেখ করেছেন: যদি AttributeErrorভিতরে .ুকে পড়ে তবে doStuff()আপনি হারিয়ে যান।

সম্ভবত এই পদ্ধতির ভাল:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

এছাড়াও ঠিক হতে পারে: try: a.propertyবাম-হাতের প্রয়োজন নেই
পেট্রুজা

তারপরে আপনাকে অন্য ব্লকে একটি ব্যক্তির পুনরাবৃত্তি করতে হবে এবং এটি ব্যর্থ হতে পারে।
এরিক আরাউজো

13

পরিস্থিতির উপর নির্ভর করে আপনি isinstanceকী ধরণের অবজেক্টের সাথে যাচাই করতে পারেন এবং তার সাথে সম্পর্কিত বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন। বিমূর্ত বেস ক্লাস প্রবর্তনের সাথেপাইথন ২.6 / 3.0.০ এ এই পদ্ধতিটি আরও বেশি শক্তিশালী হয়ে উঠেছে (মূলত এবিসিরা হাঁসের টাইপের আরও পরিশীলিত পদ্ধতিতে অনুমতি দেয়)।

দুটি পরিস্থিতি একই নামের সাথে একটি বৈশিষ্ট্যযুক্ত থাকলেও ভিন্ন অর্থ সহ যদি এটি কার্যকর হয় তবে তা কার্যকর objects শুধুমাত্র ব্যবহারhasattr পরে অদ্ভুত ত্রুটি হতে পারে।

একটি দুর্দান্ত উদাহরণ হ'ল পুনরাবৃত্তকারী এবং পুনরাবৃত্ত হওয়া ( এই প্রশ্নটি দেখুন) এর মধ্যে পার্থক্য । __iter__কোনো ইটারেটরে পদ্ধতি এবং একটি iterable নাম একই কিন্তু শব্দার্থগতভাবে পুরোপুরি ভিন্ন হয়! তাই hasattrবেহুদা, কিন্তু isinstanceএবিসি এর সঙ্গে একসঙ্গে একটি পরিষ্কার সমাধান প্রদান করে।

তবে আমি সম্মত হই যে বেশিরভাগ পরিস্থিতিতে hasattrপদ্ধতির (অন্যান্য উত্তরে বর্ণিত) সর্বাধিক উপযুক্ত সমাধান।


13

আশা করি আপনি hasattr () প্রত্যাশা করছেন, তবে hasattr () এড়ানোর চেষ্টা করুন এবং দয়া করে getattr () পছন্দ করুন। getattr () hasattr () এর চেয়ে দ্রুত

hasattr () ব্যবহার করে:

 if hasattr(a, 'property'):
     print a.property

একই এখানে আমি সম্পত্তি পাওয়ার জন্য getattr ব্যবহার করছি যদি কোনও সম্পত্তি না থাকে তবে এটি কোনও কিছুই ফেরত দেয় না

   property = getattr(a,"property",None)
    if property:
        print property

11

সম্পাদনা : এই পদ্ধতির গুরুতর সীমাবদ্ধতা রয়েছে। এটি কাজ করা উচিত যদি বস্তুটি পুনরাবৃত্তিযোগ্য হয় হয়। নীচের মন্তব্যগুলি দেখুন।

আপনি যদি আমার মতো পাইথন ৩.6 বা তার বেশি উচ্চতর ব্যবহার করে থাকেন তবে কোনও জিনিসের কোনও বিশেষ বৈশিষ্ট্য রয়েছে কিনা তা যাচাই করার জন্য একটি সুবিধাজনক বিকল্প রয়েছে:

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

যাইহোক, আমি নিশ্চিত নই যে এই মুহূর্তে সেরা পদ্ধতির। ব্যবহার hasattr(), ব্যবহার getattr()বা ব্যবহার in। মন্তব্য স্বাগত।


6
inকীওয়ার্ড পুনরাবৃত্তিযোগ্য প্রকারগুলি পরীক্ষা করার জন্য কাজ করে। উদাহরণস্বরূপ, 'foo' in Noneত্রুটি ছুড়ে ফেলে TypeError: argument of type 'NoneType' is not iterable। সমাধানটি পরীক্ষা করার আগে টাইপটি পুনরায় ব্যবহারযোগ্য কিনা তা পরীক্ষা করা উচিত in। অ-পুনরাবৃত্ত প্রকারের মতো প্রান্তের ক্ষেত্রে সংশোধন করার পরে, আপনি সম্ভবত ব্যবহার করা ভাল hasattr()কারণ এটি প্রান্তের কেসগুলি হ্যান্ডেল করার জন্য তৈরি করা হয়েছে।
শেঠ ডিফলি

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

2
যদি ক্লাসে 'ভেরিয়েবল' হয় __
বেন


1

আপনি objectব্যবহার করে বৈশিষ্ট্য রয়েছে কিনা তা পরীক্ষা করতে পারেনhasattrবিল্টিন পদ্ধতিটি বিশিষ্টতা ।

উদাহরণস্বরূপ যদি আপনার অবজেক্ট হয় aএবং আপনি গুনটি পরীক্ষা করতে চানstuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

পদ্ধতিটির স্বাক্ষরটিই এর hasattr(object, name) -> boolঅর্থ যার দ্বারা বুলিয়ান দেয় বা অবজেক্টে অ্যাট্রিবিটির উপস্থিতি অনুসারে দ্বিতীয় আর্গুমেন্টে অ্যাট্রিবিউট দেওয়া থাকে যদি objectতার গুণাবলী থাকে।hasattrTrueFalsename


1

এটি অত্যন্ত সহজ, কেবলমাত্র dir(অবজেক্ট ব্যবহার করুন )
এটি প্রতিটি উপলভ্য ক্রিয়াকলাপ এবং অবজেক্টের বৈশিষ্ট্যের একটি তালিকা ফিরিয়ে দেবে।


1

আর একটি সম্ভাব্য বিকল্প, তবে এটি আপনি যদি আগে বোঝাতে চেয়েছিলেন তা নির্ভর করে :

undefined = object()

class Widget:

    def __init__(self):
        self.bar = 1

    def zoom(self):
        print("zoom!")

a = Widget()

bar = getattr(a, "bar", undefined)
if bar is not undefined:
    print("bar:%s" % (bar))

foo = getattr(a, "foo", undefined)
if foo is not undefined:
    print("foo:%s" % (foo))

zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
    zoom()

আউটপুট:

bar:1
zoom!

এটি আপনাকে এমনকি কোনও মূল্যবান বৈশিষ্ট্যও পরীক্ষা করতে দেয়।

কিন্ত! আপনি দুর্ঘটনাক্রমে undefinedএকাধিক জায়গাগুলি তাত্ক্ষণিকভাবে তুলনা এবং তুলনা না করার বিষয়ে খুব সতর্ক থাকুন কারণ সে isক্ষেত্রে কখনই কাজ করবে না।

হালনাগাদ:

উপরের অনুচ্ছেদে আমি যে বিষয়ে সতর্ক করেছিলাম তার কারণেই, একাধিক অপরিজ্ঞাত যা কখনও মেলে না, আমি সম্প্রতি এই প্যাটার্নটিতে কিছুটা সংশোধন করেছি:

undefined = NotImplemented

NotImplementedবিভ্রান্ত হওয়ার মতো নয় NotImplementedError, এটি একটি অন্তর্নির্মিত: এটি কোনও জেএসের অভিপ্রায়কে অর্ধমুখে মেলে undefinedএবং আপনি তার সংজ্ঞাটি যে কোনও জায়গায় আবার ব্যবহার করতে পারেন এবং এটি সর্বদা মিলবে। ত্রুটিগুলি হ'ল এটি বুলিয়ান্সে "সত্যবাদী" এবং এটি লগ এবং স্ট্যাকের চিহ্নগুলিতে অদ্ভুত লাগতে পারে (তবে আপনি যখন জানবেন যে এটি কেবলমাত্র এই প্রসঙ্গে প্রদর্শিত হয়)


0

hasattr()সঠিক উত্তর। আমি যা যুক্ত করতে চাই তা হ'ল hasattr()দৃ as ়তার সাথে একযোগে ব্যবহার করা যেতে পারে (অপ্রয়োজনীয় ifবক্তব্য এড়াতে এবং কোডটি আরও পাঠযোগ্য করে তোলার জন্য):

assert hasattr(a, 'property'), 'object lacks property' 

এসও-তে অন্য উত্তরে যেমন বলা হয়েছে : দৃ As ়তাগুলি এমন শর্তগুলির পরীক্ষা করতে ব্যবহার করা উচিত যা কখনই না ঘটে should উদ্দেশ্যটি হ'ল কোনও দুর্নীতিগ্রস্থ প্রোগ্রামের ক্ষেত্রে তাড়াতাড়ি ক্রাশ করা।


এটি হেল্পফুল তবে সর্বদা এটি নাও হতে পারে। সম্ভবত আমি পরীক্ষা করতে চেয়েছিলাম যে যদি সেই বস্তুর কোনও সম্পত্তি আছে এবং তারপরে এটি প্রথমবার যুক্ত করলাম, বা সম্ভবত আমাকে সেই সম্পত্তি যুক্ত বস্তুর জন্য আলাদা কোড চালাতে হবে। কোডটি চালিয়ে যেতে না পারলে দৃsert়পদ ঠিক হয়ে যেতে পারে। কিন্তু আবার, সবসময় ক্ষেত্রে হয় না। গুরুত্বপূর্ণ জিনিসটি hasattrআশেপাশের কোডটি না ব্যবহার করা ।
লুকাস গ্যাব্রিয়েল সানচেজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.