سؤال

أنا استيراد من ملف CSV و الحصول على البيانات تقريبا في الشكل

{ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }

أسماء المجالات الحيوية.(حسنا, أنهم ديناميكية في أنه قد يكون هناك أكثر من field1 ومن ثم Field2, ولكن أعلم Field1 و Field2 دائما ستكون هناك.

أود أن تكون قادرة على تمرير في هذا القاموس في صفي allMyFields بحيث لا يمكن الوصول إلى البيانات المذكورة أعلاه من الخصائص.

class allMyFields:
    # I think I need to include these to allow hinting in Komodo. I think.
    self.Field1 = None
    self.Field2 = None

    def __init__(self,dictionary):
        for k,v in dictionary.items():
            self.k = v
            #of course, this doesn't work. I've ended up doing this instead
            #self.data[k] = v
            #but it's not the way I want to access the data.

q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)
# Ideally I could do this.
print q.Field1

أي اقتراحات ؟ بقدر ما السبب .. أود أن تكون قادرة على الاستفادة من رمز ملمحا و استيراد البيانات إلى قاموس يسمى data كما كنت أفعل لا تحمل لي أي من ذلك.

(منذ أسماء المتغيرات لا تحل حتى وقت التشغيل, أنا لا تزال تنوي رمي العظام إلى كومودو - أعتقد أن self.Field1 = None ينبغي أن يكون كافيا.)

حتى كيف أفعل ما أريد ؟ أو أنا تنبح سوء تصميم غير بيثون الشجرة ؟

هل كانت مفيدة؟

المحلول

يمكنك استخدام setattr (كن حذرا على الرغم من:ليس كل السلسلة هو سمة صالح اسم!):

>>> class AllMyFields:
...     def __init__(self, dictionary):
...         for k, v in dictionary.items():
...             setattr(self, k, v)
... 
>>> o = AllMyFields({'a': 1, 'b': 2})
>>> o.a
1

تحرير: اسمحوا لي أن أشرح الفرق بين رمز أعلاه ، SilentGhost الجواب.رمز أعلاه مقتطف يخلق الدرجة التي سبيل المثال سمات على أساس معين القاموس.SilentGhost رمز يخلق الدرجة التي سمات الطبقة على أساس معين القاموس.

اعتمادا على الوضع الخاص بك محددة أي من هذه الحلول قد تكون أكثر ملاءمة.هل عادي لإنشاء واحد أو أكثر من فئة الحالات ؟ إذا كان الجواب هو واحد يمكنك تخطي إنشاء كائن تماما و إلا بناء نوع (وبالتالي تذهب مع SilentGhost الجواب).

نصائح أخرى

>>> q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
>>> q = type('allMyFields', (object,), q)
>>> q.Field1
3000

type توضح جيدا ما يحدث هنا (انظر استخدامها بوصفها منشئ ).

تحرير : في حال كنت بحاجة المتغيرات سبيل المثال، يعمل يلي أيضا:

>>> a = q()             # first instance
>>> a.Field1
3000
>>> a.Field1 = 1
>>> a.Field1
1
>>> q().Field1           # second instance
3000

ويمكنك أيضا استخدام dict.update بدلا من حلقات يدويا على items (وإذا كنت حلقات، iteritems هي أحسن).

class allMyFields(object):
    # note: you cannot (and don't have to) use self here
    Field1 = None
    Field2 = None

    def __init__(self, dictionary):
        self.__dict__.update(dictionary)

q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)

print instance.Field1      # => 3000
print instance.Field2      # => 6000
print instance.RandomField # => 5000

وعن طريق الصفوف المسماة (بيثون 2.6):

>>> from collections import namedtuple

>>> the_dict = {'Field1': 3, 'Field2': 'b', 'foo': 4.9}
>>> fields = ' '.join(the_dict.keys())
>>> AllMyFields = namedtuple('AllMyFields', fields)
>>> instance = AllMyFields(**the_dict)

>>> print instance.Field1, instance.Field2, instance.foo
3 b 4.9

هل يمكن أن تجعل فئة فرعية من dict الذي يسمح بحث سمة لمفاتيح:

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

q = AttributeDict({ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 })
print q.Field1              
print q.Field2              
print q.RandomField

إذا كنت في محاولة للبحث عن السمة التي dict بالفعل (ويقول keys أو get)، ستحصل على أن سمة فئة dict (طريقة). إذا كان مفتاح تسأل عن غير موجود على الطبقة dict، ثم سوف تحصل على استدعاء الأسلوب __getattr__، وسوف نفعل بحث رئيسيا الخاص بك.

استخدم setattr للطريقة جميلة. الطريق السريع ن القذرة هي تحديث القاموس الداخلي المثال:

>>> class A(object):
...    pass
...
>>> a = A()
>>> a.__dict__.update({"foo": 1, "bar": 2})
>>> a.foo
1
>>> a.bar
2
>>>
class SomeClass:
    def __init__(self,
                 property1,
                 property2):
       self.property1 = property1
       self.property2 = property2


property_dict = {'property1': 'value1',
                 'property2': 'value2'}
sc = SomeClass(**property_dict)
print(sc.__dict__)

وأو يمكنك محاولة هذا

class AllMyFields:
    def __init__(self, field1, field2, random_field):
        self.field1 = field1
        self.field2 = field2
        self.random_field = random_field

    @classmethod
    def get_instance(cls, d: dict):
        return cls(**d)


a = AllMyFields.get_instance({'field1': 3000, 'field2': 6000, 'random_field': 5000})
print(a.field1)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top