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


133

আইসি # আমরা প্রতিবিম্বের মাধ্যমে এটি করি। জাভাস্ক্রিপ্টে এটি সহজ:

for(var propertyName in objectName)
    var currentPropertyValue = objectName[propertyName];

পাইথনে এটি কীভাবে করবেন?



3
দয়া করে মনে রাখবেন যে এই প্রশ্নটি একটি ভুল ব্যবহারকারীর। বেশিরভাগ উত্তর সদস্যদের গণনা সম্পর্কে । আমি বৈশিষ্ট্যগুলি গণনা করার একটি উপায় খুঁজছিলাম , অর্থাত্ সজ্জিত কোনও শ্রেণীর সদস্য @property
টমাসজ গ্যান্ডার

উত্তর:


153
for property, value in vars(theObject).iteritems():
    print property, ": ", value

সচেতন একটি আছে যে কিছু বিরল ক্ষেত্রে হউন __slots__সম্পত্তি, এই ধরনের শ্রেণীর প্রায়ই নাই __dict__


1
এখন কিভাবে মান পরিবর্তন? জাভাস্ক্রিপ্টে আপনি এটি করতে পারেন: অবজেক্ট [সম্পত্তি] = নতুন মূল্য। পাইথনে এটি কীভাবে করবেন?
জাদের দিয়া

39
পরিবর্তে setattr () ব্যবহার করুন।
নেলসন

1
@ নেলসন আপনি কি আরও ভাল বিকল্পটি ব্যাখ্যা করতে পারেন? এটি কি আরও খাটো, নাকি অতিরিক্ত বিবেচনা রয়েছে?
নটহাগো

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

3
@ হাই-স্বর্গদূত করে হবে। যাইহোক, যা কাজ করছে না তা হ'ল পাইথনের গতিশীল অবজেক্ট সদস্যের বিপরীতে আপনার আশেপাশের অবস্থান সম্পর্কিত পূর্ব ধারণা এবং অনুমানের নক্ষত্রমণ্ডল। vars()কেবল স্থিতিশীল সদস্যদের (যেমন, বস্তুর বৈশিষ্ট্য এবং সেই বস্তুর সাথে নিবন্ধিত পদ্ধতিগুলি __dict__) ফেরত দেয় । এটি গতিশীল সদস্যদের (যেমন, বস্তুর বৈশিষ্ট্য এবং পদ্ধতিগুলি বস্তুর পদ্ধতি বা অনুরূপ যাদু দ্বারা গতিশীলভাবে সংজ্ঞায়িত ) ফেরত দেয় না । সমস্ত সম্ভাবনায় আপনার পছন্দসই সম্পত্তি গতিশীলভাবে সংজ্ঞায়িত করা হয় এবং তাই বা এগুলি উপলভ্য নয়__getattr__()file.ImplementationNamevars()dir()
সিসিল কারি

69

দেখুন inspect.getmembers(object[, predicate])

নামের সাথে বাছাই করা (নাম, মান) জোড়ার তালিকায় কোনও অবজেক্টের সমস্ত সদস্যকে ফিরিয়ে দিন। যদি alচ্ছিক প্রাকটিকেট যুক্তি সরবরাহ করা হয় তবে কেবলমাত্র সেই সদস্যদের জন্য যার জন্য ভবিষ্যদ্বাণীক একটি সত্য মান দেয়।

>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__',    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__', 
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', 
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 

হ্যাঁ, এই উত্তরটি দুর্দান্ত; এই মডিউলটি আগে কখনও ব্যবহার করিনি। গেটমেম্বার্স () কেবল ডির (অবজেক্ট), বিটিডব্লিউর ফলাফলগুলি হাঁটা দ্বারা প্রয়োগ করা হয়।
নেলসন

ডিক অ্যাক্সেস করার চেয়ে এটি কেন ভাল তা আপনি ব্যাখ্যা করতে পারেন ? পাইথন ডকুমেন্টেশন সহায়ক থেকে কম নয়, বিশেষত কারণ এটি সাধারণত এই শব্দটি attributesব্যবহার করে members(উভয়ের মধ্যে কোনও পার্থক্য আছে?)। নামটি ধারাবাহিক করতে তারা পাইথন 3.0 এ নামটি স্থির করতে পারত।
নিকো

ওফ, মানে __dict__, দুঃখিত।
নিকো

4
@ নাইকো: ইন্সপেক্ট.গেটেমেমার্স () অভ্যন্তরীণ বিশদ পরিবর্তন হলে এমনকি কাজ চালিয়ে যাওয়ার গ্যারান্টিযুক্ত।
জর্জি স্কলি

3
@ নিকোলাসকাইটে ( ডাব্লিক ক্লাস অ্যাট্রিবিউটস এবং মেটাক্লাস অ্যাট্রিবিউটস এবং (বি) পাশ করা প্রাক্কলকের সাথে মেলে না এমন সদস্যদের বাদ দিয়ে (এ) এর (বেশিরভাগ नगणিক ) সাইড বেনিফিট সহ inspect.getmembers()মোড়ানো dir()) হ্যাঁ, তাই না? তৃতীয় পক্ষের গ্রন্থাগারগুলির জন্য যথাযথভাবে সমস্ত সম্ভাব্য বস্তুর প্রকারকে সমর্থন করা উপযুক্ত। স্ট্যান্ডার্ড ব্যবহারের ক্ষেত্রে, তবে একেবারে যথেষ্ট। inspect.getmembers()dir()
সিসিল কারি

66

dir()সহজ উপায়। এখানে দেখো:

পাইথন ইন্ট্রোস্পেকশন গাইড


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

1
ক্লাইমে স্ক্র্যাচ কাজ করার সময় এই উত্তরটি সবচেয়ে ভাল।

পাইথনের 15 বছর (পুরো সময়ের চাকরি কখনও হয়নি) এবং আমি dir()আপনাকে ধন্যবাদ ভুলে গেছি ।
অভিষেক দুজারি

14

__dict__বস্তুর সম্পত্তি সব তার অন্যান্য সংজ্ঞায়িত বৈশিষ্ট্য একটি অভিধান আছে। দ্রষ্টব্য যে পাইথন ক্লাসগুলি getattr ওভাররাইড করতে পারে এবং এমন বৈশিষ্ট্য তৈরি করতে পারে যা বৈশিষ্ট্যের মতো দেখায় কিন্তু এতে নেই __dict__। বিল্টিন ফাংশনগুলিও রয়েছে vars()এবং dir()যা সূক্ষ্ম উপায়ে পৃথক। এবং কিছু অস্বাভাবিক ক্লাসে __slots__প্রতিস্থাপন করতে পারেন __dict__

পাইথনে বস্তুগুলি জটিল complicated __dict__প্রতিবিম্ব-স্টাইল প্রোগ্রামিংয়ের জন্য শুরু করার সঠিক জায়গা। dir()আপনি যদি একটি ইন্টারেক্টিভ শেলের চারপাশে হ্যাক করছেন তবে এটি শুরু করার জায়গা।


print vars.__doc__ইঙ্গিত দেয় যে With an argument, equivalent to object.__dict__সূক্ষ্ম পার্থক্য কি হবে?
সানচো.স পুনরায় ইনস্টল করুনমনিকাসেলিও


10

আপনি যদি সমস্ত বৈশিষ্ট্যের প্রতিচ্ছবি সন্ধান করেন তবে উপরের উত্তরগুলি দুর্দান্ত।

যদি আপনি কেবল অভিধানের কীগুলি (যা পাইথনের কোনও 'অবজেক্ট' থেকে পৃথক) পাওয়ার সন্ধান করে থাকেন তবে ব্যবহার করুন

my_dict.keys()

my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys() 
> ['abc', 'def', 'ghi']

1
যদিও এটি আমার উত্তর, আমি মনে করি এটি গ্রহণযোগ্য উত্তর হওয়া উচিত নয়: কোনও জিনিসের কীগুলি কোনও শ্রেণীর অবজেক্টের উদাহরণ থেকে পৃথক। এগুলি আলাদাভাবে অ্যাক্সেস করা হয়েছে ( obj['key']বনাম obj.property) এবং প্রশ্নটি ছিল বস্তুর বৈশিষ্ট্য সম্পর্কে। আমি আমার উত্তর এখানে রেখেছি কারণ দুজনের মধ্যে সহজেই বিভ্রান্তি রয়েছে।
মিঃ

আমি আসলে এই উত্তরটি সরানোর পরামর্শ দেব would
এন্টার

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

এবং আপনি ঠিক বলেছেন, তবে বিষয়টিটি মিস করুন: অন্যান্য ভাষায় (জেএস নিন) বস্তু এবং অভিধানের মধ্যে কোনও পার্থক্য নেই। প্রশ্নটি জিজ্ঞাসা করে সি # থেকে ওপি আসে। এই উত্তরটি ভুল হলেও 11 টি উত্সাহ পেয়েছে, প্রমাণ পেয়েছে যে এখানে যারা অবতরণ করেছে তারা লোকেদের এটি দরকারী বলে মনে করে, যদিও এটি প্রযুক্তিগতভাবে সঠিক উত্তর নয় (যেমন আমি উল্লেখ করেছি) এটি কঠোর অজগর লিঙ্গে দেখার সময় প্রশ্নের উত্তর দেয়। আমি এটিকে আরও স্ফটিক পরিষ্কার করার জন্য সম্পাদনা করব।
মিঃ

5

এটি সম্পূর্ণরূপে অন্যান্য উত্তরগুলির সাথে আচ্ছাদিত, তবে আমি এটি স্পষ্ট করে দেব। একটি অবজেক্টের ক্লাস অ্যাট্রিবিউটস এবং স্ট্যাটিক এবং ডায়নামিক ইনস্ট্যান্ট অ্যাট্রিবিউট থাকতে পারে।

class foo:
    classy = 1
    @property
    def dyno(self):
        return 1
    def __init__(self):
        self.stasis = 2

    def fx(self):
        return 3

stasisস্থিতিশীল, dynoগতিশীল (সিএফ। সম্পত্তি সজ্জা) এবং classyএটি একটি শ্রেণি বৈশিষ্ট্য। আমরা যদি সহজভাবে করি __dict__বা আমরা কেবল varsস্থির একটি পাই।

o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}

সুতরাং আমরা চাইলে অন্যরা __dict__সবকিছু (এবং আরও কিছু) পাবে। এর মধ্যে রয়েছে যাদু পদ্ধতি এবং বৈশিষ্ট্য এবং সাধারণ গণ্ডিযুক্ত পদ্ধতি। সুতরাং এগুলি এড়ানো যাক:

d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}

typeএকটি সম্পত্তি সজ্জিত পদ্ধতি (একটি গতিশীল বৈশিষ্ট্য) সঙ্গে বলা তোমরা প্রত্যাবর্তিত মানের প্রকার দিতে, হবে না method। এটি প্রমাণ করার জন্য আসুন জসন এটির স্ট্রিংফাই করুন:

import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}

এটি যদি কোনও পদ্ধতি হত তবে এটি ক্র্যাশ হত।

টি এল; ডিআর। extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}তিনটি জন্য কল করার চেষ্টা করুন , কিন্তু পদ্ধতি বা জাদু নয়।

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