2010-07-26 12 views
30

जावास्क्रिप्ट में ऑब्जेक्ट अक्षर हैं, उदा।वस्तु अक्षर पाइथनिक हैं?

var p = { 
    name: "John Smith", 
    age: 23 
} 

और .NET के पास अनाम प्रकार हैं, उदा।

var p = new { Name = "John Smith", Age = 23}; // C# 

कुछ इसी तरह की (ab) नामित तर्क का उपयोग करके अजगर में नकल करते जा सकता है:

class literal(object): 
    def __init__(self, **kwargs): 
     for (k,v) in kwargs.iteritems(): 
      self.__setattr__(k, v) 
    def __repr__(self): 
     return 'literal(%s)' % ', '.join('%s = %r' % i for i in sorted(self.__dict__.iteritems())) 
    def __str__(self): 
     return repr(self) 

उपयोग:

p = literal(name = "John Smith", age = 23) 
print p  # prints: literal(age = 23, name = 'John Smith') 
print p.name # prints: John Smith 

लेकिन कोड इस तरह का pythonic माना जाता है?

+1

"पायथनिक", मुझे यह शब्द पसंद है! –

+3

आपके '__init__' में 'for' लूप को' self .__ dict__ = kw' –

उत्तर

34

क्या आपने named tuple का उपयोग करने पर विचार किया है?

अपने dict संकेतन का उपयोग

>>> from collections import namedtuple 
>>> L = namedtuple('literal', 'name age')(**{'name': 'John Smith', 'age': 23}) 

या कीवर्ड तर्क

>>> L = namedtuple('literal', 'name age')(name='John Smith', age=23) 
>>> L 
literal(name='John Smith', age=23) 
>>> L.name 
'John Smith' 
>>> L.age 
23 

यह एक समारोह आसानी से पर्याप्त में इस व्यवहार रैप करने के लिए

def literal(**kw): 
    return namedtuple('literal', kw)(**kw) 

लैम्ब्डा बराबर होगा संभव है

literal = lambda **kw: namedtuple('literal', kw)(**kw) 

लेकिन व्यक्तिगत रूप से मुझे लगता है कि यह मूर्खतापूर्ण देने के नाम करने के लिए "गुमनाम" कार्यों

+0

PyRec के बारे में कैसे? (http://www.valuedlessons.com/2009/10/introducing-pyrec-cure-to-bane-of-init.html) – Plumenator

+0

हां, मैंने नामित ट्यूपल को देखा है, लेकिन क्या यह DRY का उल्लंघन नहीं करता है सिद्धांत? किसी ऑब्जेक्ट को बनाने के लिए आपको प्रत्येक फ़ील्ड के नाम दो बार निर्दिष्ट करने की आवश्यकता होती है। बेशक, इसे घुमाया जा सकता है: शाब्दिक = लैम्ब्डा ** kwargs: नामित ('शाब्दिक', '.join (kwargs.keys())) (** kwargs); पी = शाब्दिक (नाम = 'जॉन स्मिथ', आयु = 23) (कोड परीक्षण नहीं किया गया है, मेरे पास Py2 नहीं है।6 मेरी मशीन पर) – ShinNoNoir

+1

@ShinNoNoir, फ़ैक्टरी फ़ंक्शन बनाने से आपके सुझाव की तुलना में थोड़ा आसान है क्योंकि 'nametuple' इसके दूसरे पैरामीटर –

59

क्यों न केवल एक शब्दकोश का उपयोग करें?

p = {'name': 'John Smith', 'age': 23} 

print p 
print p['name'] 
print p['age'] 
+8

के साथ प्रतिस्थापित किया जा सकता है आप 'dict' फ़ंक्शन का उपयोग भी कर सकते हैं:' p = dict (name =' जॉन स्मिथ ', आयु = 23) ' –

+0

खैर, हाँ, डिक्ट्स कम या ज्यादा समकक्ष हैं। इसके अलावा, टॉमसज़ का सुझाव उन्हें बनाने का एक अच्छा वैकल्पिक तरीका है। फिर भी, एक नियम के 'फ़ील्ड' तक पहुंचने से मेरे कोड उदाहरण में उतना अच्छा नहीं है, हालांकि यह केवल एक छोटी वाक्य रचनात्मक असुविधा है। – ShinNoNoir

+2

जबकि मैं सहमत हूं, मुझे लगता है कि काम पर दार्शनिक अंतर है। पायथन में प्रचलित दर्शन यह है कि यदि आपको '.name' और' .age' सदस्यों के साथ किसी ऑब्जेक्ट की आवश्यकता है, तो आपको स्पष्ट रूप से उस ऑब्जेक्ट को अपने सभी कन्स्ट्रक्टर आदि के साथ बनाना चाहिए, –

7

ActiveState से है:

class Bunch: 
    def __init__(self, **kwds): 
     self.__dict__.update(kwds) 

# that's it! Now, you can create a Bunch 
# whenever you want to group a few variables: 

point = Bunch(datum=y, squared=y*y, coord=x) 

# and of course you can read/write the named 
# attributes you just created, add others, del 
# some of them, etc, etc: 
if point.squared > threshold: 
    point.isok = 1 
2
Python IAQ से

:

अजगर 2.3 के रूप में आप उपयोग कर सकते हैं वाक्यविन्यास

dict(a=1, b=2, c=3, dee=4) 

जो कि जहां तक ​​मेरा संबंध है, उतना अच्छा है। अजगर 2.3 इससे पहले कि मैं एक पंक्ति का समारोह

def Dict(**dict): return dict 
1

इस्तेमाल किया मैं वस्तु शाब्दिक दो कारणों के लिए जावास्क्रिप्ट में समझ बनाने के बारे में सोच:

  1. जावास्क्रिप्ट में, वस्तुओं एक ही तरीका है एक "बात बनाने के लिए कर रहे हैं "स्ट्रिंग-इंडेक्स गुणों के साथ। पाइथन में, जैसा कि किसी अन्य उत्तर में बताया गया है, शब्दकोश का प्रकार ऐसा करता है।

  2. जावास्क्रिप्ट की ऑब्जेक्ट सिस्टम प्रोटोटाइप-आधारित है। जावास्क्रिप्ट में कक्षा के रूप में ऐसी कोई चीज़ नहीं है (हालांकि यह भविष्य के संस्करण में आ रही है) - वस्तुओं के वर्गों के बजाय प्रोटोटाइप ऑब्जेक्ट्स हैं। इस प्रकार एक शब्दकोष के माध्यम से "कुछ भी नहीं" वस्तु बनाना स्वाभाविक है, क्योंकि सभी वस्तुओं को केवल अंतर्निहित मूल वस्तु को प्रोटोटाइप के रूप में आवश्यक होती है।पायथन में, प्रत्येक ऑब्जेक्ट में एक वर्ग होता है - आप उन चीज़ों के लिए ऑब्जेक्ट्स का उपयोग करने की अपेक्षा करते हैं जहां आपके पास एक-ऑफ के बजाय कई उदाहरण होंगे।

इस प्रकार कोई नहीं, ऑब्जेक्ट अक्षर लिथोनिक नहीं हैं, लेकिन वे जावास्क्रिप्थोनिक हैं।

+0

जावास्क्रिप्टिक, शायद? :-) – Plumenator

+3

नहीं, यह सोडा अक्सर डोम जिन के साथ मिलाया जाता है। –

+2

मैं असहमत हूं - जावास्क्रिप्ट में वास्तव में dict-like ऑब्जेक्ट बनाने के लिए केवल एक ही तरीका है, लेकिन इसे 'obj.prop' और' obj ["prop"] 'वाक्यविन्यास के माध्यम से - एक से अधिक तरीकों से एक्सेस किया जा सकता है - जो काफी है अच्छा विचार, जिसे पाइथन में कार्यान्वित किया जा सकता है यदि कोई ऐसा चाहता है (नीचे उत्तर दें)। इसके अलावा - कक्षाएं भी वस्तुएं हैं (पायथन में) इसलिए उन्हें उपयोग करने के लिए एक बार के कंटेनर के रूप में उपयोग समय-समय पर उपयोगी हो सकता है (जब एपीआई से निपटने के लिए जो '__getattr__' उत्तीर्ण कुछ लागू करना चाहते हैं)। – cji

2

मुझे "अज्ञात" कक्षाएं/उदाहरण बनाने में कुछ भी गलत नहीं दिख रहा है। कोड की एक पंक्ति में सरल फ़ंक्शन कॉल के साथ एक बनाने के लिए अक्सर यह बहुत ही दृढ़ होता है। मैं व्यक्तिगत रूप से इस तरह कुछ उपयोग करता हूं:

def make_class(*args, **attributes): 
    """With fixed inability of using 'name' and 'bases' attributes ;)""" 
    if len(args) == 2: 
     name, bases = args 
    elif len(args) == 1: 
     name, bases = args[0], (object,) 
    elif not args: 
     name, bases = "AnonymousClass", (object,) 
    return type(name, bases, attributes) 

obj = make_class(something = "some value")() 
print obj.something 

डमी ऑब्जेक्ट्स बनाने के लिए यह ठीक काम करता है। Namedtuple ठीक है, लेकिन अपरिवर्तनीय है, जो कभी-कभी असुविधाजनक हो सकता है। और शब्दकोश है ... अच्छा, एक शब्दकोश है, लेकिन ऐसी स्थितियां हैं जब आपको के बजाय __getattr__ परिभाषित किया गया है।

मुझे नहीं पता कि यह पाइथोनिक है या नहीं, लेकिन कभी-कभी चीजों को गति देता है और मेरे लिए यह इसका उपयोग करने के लिए पर्याप्त कारण है (कभी-कभी)।

+0

'make_class' को छोड़कर दिलचस्प दृष्टिकोण वास्तव में एक वस्तु का निर्माण कर रहा है। ऐसी समस्या भी है कि आपके पास अपने दृष्टिकोण के साथ 'नाम' नामक विशेषता नहीं हो सकती है। (लेकिन मुझे लगता है कि मुझे अपनी 'शाब्दिक' कक्षा में एक ही समस्या है ... मेरे पास 'self' नामक विशेषता नहीं है)। – ShinNoNoir

+2

असल में यह 'क्लास ऑब्जेक्ट' है - यह यहां तत्काल है: 'make_class (...)() '। मुझे लगता है? और नाम के संघर्ष के रूप में - सच है। – cji

1

अधिकांश मामलों के लिए एक साधारण शब्दकोश पर्याप्त होना चाहिए।

आप देख रहे हैं एक आप शाब्दिक मामले के लिए संकेत दिया करने के लिए इसी तरह की एक एपीआई के लिए, आप अभी भी शब्दकोशों उपयोग कर सकते हैं और केवल विशेष __getattr__ समारोह को ओवरराइड:

class CustomDict(dict): 
    def __getattr__(self, name): 
     return self[name] 

p = CustomDict(user='James', location='Earth') 
print p.user 
print p.location 

नोट: फिर भी ध्यान रखें नामकरण के विपरीत, फ़ील्ड मान्य नहीं हैं और आप यह सुनिश्चित करने के प्रभारी हैं कि आपके तर्क सचेत हैं। p['def'] = 'something' जैसे तर्कों को एक शब्दकोश के भीतर सहन किया जाता है लेकिन आप उन्हें p.def के माध्यम से एक्सेस नहीं कर पाएंगे।

संबंधित मुद्दे