سؤال

لدي برنامج Python 2.6 التالي وتعريف YAML (باستخدام pyyaml.):

import yaml

x = yaml.load(
    """
        product:
           name     : 'Product X'
           sku      : 123
           features :
             - size    :  '10x30cm'
               weight  :  '10kg'

         """
    )

print type(x)
print x


مما يؤدي إلى الإخراج التالي:
<type 'dict'>
{'product': {'sku': 123, 'name': 'Product X', 'features': [{'weight': '10kg', 'size': '10x30cm'}]}}

من الممكن إنشاء كائن مع الحقول من x?

أود أن ما يلي:

print x.features[0].size

أنا أدرك أنه من الممكن إنشاء ومثال من فئة موجودة، ولكن هذا ليس ما أريده لهذا السيناريو بالذات.

تعديل:

  • تحديث الجزء المربك حول "كائن مكتوء بشدة".
  • تم تغيير الوصول إلى features إلى مفهرس كما اقترح أليكس مارتيلي
هل كانت مفيدة؟

المحلول

لذلك لديك قاموس مع مفاتيح السلسلة والقيم التي يمكن أن تكون أرقام، القواميس المتداخلة، قوائم، وترغب في التفاف ذلك في مثيل يتيح لك استخدام الوصول إلى السمة بدلا من فهرسة DICT، و "اتصل بفهرس" بدلا من فهرسة القائمة - لست متأكدا ما يجب أن يفعله "مكتوب بشدة" بهذا، أو لماذا تعتقد .features(0) أفضل من .features[0] (مثل هذه الطريقة الطبيعية لمفهرسة قائمة!)، ولكن، بالتأكيد، فمن الممكن. على سبيل المثال، قد يكون نهج بسيط:

def wrap(datum):
  # don't wrap strings
  if isinstance(datum, basestring):
    return datum
  # don't wrap numbers, either
  try: return datum + 0
  except TypeError: pass
  return Fourie(datum)

class Fourie(object):
  def __init__(self, data):
    self._data = data
  def __getattr__(self, n):
    return wrap(self._data[n])
  def __call__(self, n):
    return wrap(self._data[n])

لذا x = wrap(x['product']) يجب أن تعطيك رغبتك (لماذا تريد تخطي هذا المستوى عندما يحتاج المنطق الخاص بك بشكل عام x.product.features(0).size, ليس لدي أي فكرة، ولكن من الواضح أن تخطي أفضل تطبيقها بشكل أفضل عند نقطة المكالمة بدلا من ترميز صلب في فئة المجمع أو وظيفة مصنع المجمع الذي أظهرته للتو).

تعديل: كما يقول المرجع إنه يريد features[0] عوضا عن features(0), ، ما عليك سوى تغيير آخر سطرين ل

  def __getitem__(self, n):
    return wrap(self._data[n])

أي، تحديد __getitem__ (الطريقة السحرية الفهرسة الأساسية) بدلا من __call__ (الأسلوب السحري الأساسية للمكالمة).

البديل "من فئة موجودة" (هنا، Fourie) ستكون لإنشاء فئة جديدة على الطاير بناء على intractived dict ملفوفة - ممكن، جدا، ولكن رمادي غامق للغاية، إن لم يكن في الواقع أسود, والسحر ودون أي ميزة تشغيلية حقيقية يمكنني التفكير فيها.

إذا كان بإمكان المرجع الاختبأ أن يوضح بالضبط السبب في أن يكون Hankering بعد قمم البرمجة التلوي لخلق فصول على الطاير، فما ميزة يعتقد أنه قد يحصل على بهذه الطريقة، وما إلى ذلك، سأعرض كيفية القيام بذلك (وربما، ربما، سأعرض أيضا لماذا الإرادة المشاهتة للحصول على ميزة ليس في الواقع يكون هناك ؛-). لكن البساطة هي نوعية مهمة في أي مسعى برمجة، واستخدام "سحر الظلام العميق" عندما يكون كود سهل ومباشر مثل الأعمال المذكورة أعلاه على ما يرام فقط، ليست أفضل الأفكار!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top