سؤال

أود الحصول على بعض واصفات البيانات كجزء من الفصل.بمعنى أنني أرغب في أن تكون سمات الفصل في الواقع خصائص ، يتم التعامل مع الوصول إليها بواسطة طرق الفصل.

يبدو أن بايثون لا تدعم هذا بشكل مباشر ، ولكن يمكن تنفيذه عن طريق التصنيف الفرعي type صف دراسي.لذلك إضافة خاصية إلى فئة فرعية من type سوف يسبب مثيلاتها أن يكون واصفات لتلك الخاصية.مثيلاتها هي الطبقات.وهكذا ، واصفات الطبقة.

هل هذا مستحسن?هل هناك أي غوتشاس يجب أن احترس?

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

المحلول

إنه اصطلاح (عادة) ، بالنسبة للواصف ، عند الوصول إليه في فئة ، لإرجاع كائن الواصف نفسه.هذا هو ما property هل;إذا قمت بالوصول إلى كائن خاصية في فئة ، فستحصل على كائن الخاصية مرة أخرى (لأن هذا هو ما هو عليه __get__ طريقة يختار القيام به).لكن هذه اتفاقية;ليس عليك أن تفعل ذلك بهذه الطريقة.

لذلك ، إذا كنت بحاجة فقط إلى الحصول على جالبة واصف على صفك ، وكنت لا تمانع في أن محاولة لتعيين سوف الكتابة فوق واصف ، يمكنك أن تفعل شيئا من هذا القبيل مع عدم وجود برمجة ميتاكلاس:

def classproperty_getter_only(f):
    class NonDataDescriptor(object):
        def __get__(self, instance, icls):
            return f(icls)
    return NonDataDescriptor()

class Foo(object):

    @classproperty_getter_only
    def flup(cls):
        return 'hello from', cls

print Foo.flup
print Foo().flup

ل

('hello from', <class '__main__.Foo'>)
('hello from', <class '__main__.Foo'>)

إذا كنت تريد واصف بيانات كامل ، أو تريد استخدام كائن الخاصية المدمج ، فأنت على حق يمكنك استخدام ميتاكلاس ووضعه هناك (إدراك أن هذه السمة ستكون غير مرئية تماما من مثيلات صفك;لا يتم فحص ميتاكلاسيس عند القيام بحث السمة على مثيل فئة).

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

نصائح أخرى

هل هذا ما تعنيه ب "سمات الطبقة لتكون في الواقع خصائص, الذي يتم التعامل مع أساليب الطبقة الوصول"?

يمكنك استخدام الديكور property لجعل الوصول يبدو أنه عضو بيانات فعلي.ثم ، يمكنك استخدام x.setter الديكور لجعل واضعة لتلك السمة.

تأكد من أن ترث من object, ، أو هذا لن ينجح.

class Foo(object):
    def __init__(self):
            self._hiddenx = 3
    @property
    def x(self):
            return self._hiddenx + 10
    @x.setter
    def x(self, value):
            self._hiddenx = value

p = Foo()

p.x #13

p.x = 4
p.x #14
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top