2012-07-24 1 views
78

में ऑब्जेक्ट विशेषताओं पर Iterate मेरे पास कई विशेषताओं और विधियों के साथ एक अजगर वस्तु है। मैं ऑब्जेक्ट विशेषताओं पर पुन: प्रयास करना चाहता हूं।पायथन

class my_python_obj(object): 
    attr1='a' 
    attr2='b' 
    attr3='c' 

    def method1(self, etc, etc): 
     #Statements 

मैं एक शब्दकोश युक्त वस्तुओं की सभी विशेषताओं और उनके वर्तमान मान उत्पन्न करना चाहते हैं, लेकिन मैं एक गतिशील रास्ते में यह करने के लिए (ताकि बाद में अगर मैं एक और विशेषता जोड़ने मैं करने के लिए याद नहीं करना चाहती मेरे फ़ंक्शन को भी अपडेट करें)।

PHP चर में कुंजी के रूप में उपयोग किया जा सकता है, लेकिन पायथन में ऑब्जेक्ट्स अनुसूचित हैं और यदि मैं इसके लिए डॉट नोटेशन का उपयोग करता हूं तो यह मेरे var के नाम से एक नई विशेषता बनाता है, जो मेरा इरादा नहीं है।

बातें स्पष्ट बस बनाने के लिए:

def to_dict(self): 
    '''this is what I already have''' 
    d={} 
    d["attr1"]= self.attr1 
    d["attr2"]= self.attr2 
    d["attr3"]= self.attr3 
    return d 

·

def to_dict(self): 
    '''this is what I want to do''' 
    d={} 
    for v in my_python_obj.attributes: 
     d[v] = self.v 
    return d 

अद्यतन: गुण मैं इस वस्तु का केवल चर, नहीं तरीकों मतलब है।

+2

http://stackoverflow.com/questions/1251692/how- टू-एन्युमरेट-ए-ऑब्जेक्ट्स-प्रॉपर्टी-इन-पायथन कुछ मदद की हो सकती है। – sean

+0

@sean विशेष रूप से, http://stackoverflow.com/a/1251789/4203 जाने का रास्ता है; आप कॉल करने योग्य को पार करने के लिए वैकल्पिक 'predicate' तर्क का उपयोग करेंगे जो फ़िल्टर (बाध्य?) फ़ंक्शंस को फ़िल्टर करेगा (जो विधियों से छुटकारा पाता है)। –

उत्तर

133

आप यह मानते हुए

>>> class Cls(object): 
...  foo = 1 
...  bar = 'hello' 
...  def func(self): 
...   return 'call me' 
... 
>>> obj = Cls() 

dir बुला पर वस्तु तुम वापस अजगर विशेष गुण सहित उस वस्तु की सभी विशेषताओं, देता है के रूप में एक वर्ग इस तरह के है। हालांकि कुछ ऑब्जेक्ट गुण कॉल करने योग्य हैं, जैसे तरीकों।

>>> dir(obj) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo', 'func'] 

आप सूची समझ का उपयोग कर हमेशा विशेष तरीकों को फ़िल्टर कर सकते हैं।

>>> [a for a in dir(obj) if not a.startswith('__')] 
['bar', 'foo', 'func'] 

या यदि आप मानचित्र/फ़िल्टर पसंद करते हैं।

>>> filter(lambda a: not a.startswith('__'), dir(obj)) 
['bar', 'foo', 'func'] 

आप तरीकों को फ़िल्टर करना चाहते हैं, तो आप अंतर्निहित callable एक चेक के रूप में उपयोग कर सकते हैं।

>>> [a for a in dir(obj) if not a.startswith('__') and not callable(getattr(obj,a))] 
['bar', 'foo'] 

आप अपनी कक्षा और उसके माता-पिता के बीच अंतर का भी निरीक्षण कर सकते हैं।

>>> set(dir(Cls)) - set(dir(object)) 
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__']) 
+1

यह एक बुरा विचार है, मैं इसे भी सुझाव नहीं दूंगा, लेकिन यदि आप जा रहे हैं, तो कम से कम चेतावनी प्रदान करें। – Julian

+1

@ जुलिएन मैंने सोचा कि कोड आत्म व्याख्यात्मक है। कौन सा हिस्सा अस्पष्ट है? हालांकि, गतिशील भाषाओं का पूरा बिंदु यह करने की क्षमता है, भले ही जावा पृष्ठभूमि के लोग मानते हैं कि यह आत्महत्या है। – Meitham

+0

यह सीधा लगता है। चेतावनी के साथ आपका क्या मतलब है? क्या गलत हो सकता था? –

0

इसका सही उत्तर यह है कि आपको नहीं करना चाहिए। यदि आप इस प्रकार की चीज चाहते हैं तो बस एक नियम का प्रयोग करें, या आपको स्पष्ट रूप से कुछ कंटेनर में विशेषताओं को जोड़ना होगा। आप सजावटी के बारे में सीखकर इसे स्वचालित कर सकते हैं।

विशेष रूप से, वैसे, आपके उदाहरण में method1 एक विशेषता के समान ही है।

+1

हाँ, मुझे पता है कि मुझे नहीं करना चाहिए .. लेकिन यह मुझे समझने में मदद करता है कि चीजें कैसे काम करती हैं। मैं एक PHP पृष्ठभूमि से आया हूं और रोज़ाना इस तरह की चीजें करने के लिए प्रयोग किया जाता है –

+0

पुरानी आदतों को तोड़ने के लिए एक अच्छा समय लगता है :)! – Julian

+0

आपने मुझे विश्वास दिलाया है। अद्यतित to_dict() विधि को रखते हुए अब तक किसी भी उत्तर से कहीं अधिक सरल है। –

2

पाइथन में ऑब्जेक्ट्स __dict__ नामक एक नियम में उनके गुण (कार्यों सहित) स्टोर करते हैं। आप सीधे गुणों तक पहुंचने के लिए इसका उपयोग कर सकते हैं (लेकिन आम तौर पर नहीं)। यदि आप सिर्फ एक सूची चाहते हैं, तो आप dir(obj) पर भी कॉल कर सकते हैं, जो सभी विशेषता नामों के साथ एक पुनरावर्तनीय लौटाता है, जिसे आप getattr पर भेज सकते हैं।

हालांकि, चर के नामों के साथ कुछ भी करने की आवश्यकता आमतौर पर खराब डिजाइन है। उन्हें संग्रह में क्यों न रखें?

class Foo(object): 
    def __init__(self, **values): 
     self.special_values = values 

फिर आप के साथ चाबियाँ पर पुनरावृति कर सकते हैं for key in obj.special_values:

+0

क्या आप कुछ और समझ सकते हैं कि मैं जो कुछ हासिल करना चाहता हूं उसे संग्रहित करने के लिए मैं संग्रह का उपयोग कैसे करूं? –

+1

मैं गतिशील रूप से ऑब्जेक्ट में विशेषताओं को जोड़ नहीं रहा हूं। मेरे पास जो चर हैं, वे लंबे समय तक समान रहेंगे, हालांकि मुझे लगता है कि ऐसा कुछ करने में सक्षम होना अच्छा होगा जैसा मेरा इरादा है। –

1
class someclass: 
     x=1 
     y=2 
     z=3 
     def __init__(self): 
      self.current_idx = 0 
      self.items = ["x","y","z"] 
     def next(self): 
      if self.current_idx < len(self.items): 
       self.current_idx += 1 
       k = self.items[self.current_idx-1] 
       return (k,getattr(self,k)) 
      else: 
       raise StopIteration 
     def __iter__(self): 
      return self 

तो सिर्फ एक iterable

s=someclass() 
for k,v in s: 
    print k,"=",v 
+0

यह बहुत जटिल लगता है। अगर मेरे पास कोई विकल्प नहीं है, तो मैं अभी जो कर रहा हूं उसके साथ रहूंगा। –

31
सामान्य रूप में

के रूप में यह फोन अपने वर्ग और दोहराएं में एक __iter__ विधि डाल ऑब्जेक्ट विशेषताओं के माध्यम से या इस कक्षा में अपनी कक्षा में रखें।

class IterMixin(object): 
    def __iter__(self): 
     for attr, value in self.__dict__.iteritems(): 
      yield attr, value 

आपका वर्ग:

>>> class YourClass(IterMixin): pass 
... 
>>> yc = YourClass() 
>>> yc.one = range(15) 
>>> yc.two = 'test' 
>>> dict(yc) 
{'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 'two': 'test'} 
0

अजगर के लिए अजगर 3,6

class SomeClass: 

    def attr_list1(self, should_print=False): 

     for k in self.__dict__.keys(): 
      v = self.__dict__.__getitem__(k) 
      if should_print: 
       print(f"attr: {k} value: {v}") 

    def attr_list(self, should_print=False): 

     b = [(k, v) for k, v in self.__dict__.items()] 
     if should_print: 
      [print(f"attr: {a[0]} value: {a[1]}") for a in b] 
     return b 
0

के लिए 3,6

class SomeClass: 

    def attr_list(self, should_print=False): 

     items = self.__dict__.items() 
     if should_print: 
      [print(f"attribute: {k} value: {v}") for k, v in items] 

     return items