كيفية استدعاء خاصية الفئة الأساسية إذا تم الكتابة فوق هذه الخاصية في الفئة المشتقة؟

StackOverflow https://stackoverflow.com/questions/1021464

سؤال

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

لكنني الآن عالق لأن بعض الحروف أو أدوات الضبط السابقة كانت تستدعي الطريقة المقابلة للفئة الأساسية ثم تنفذ شيئًا آخر.ولكن كيف يمكن تحقيق ذلك مع الخصائص؟كيفية استدعاء حاصل الملكية أو واضعها في الفئة الأصل؟

بالطبع مجرد استدعاء السمة نفسها يعطي تكرارًا لا نهائيًا.

class Foo(object):

    @property
    def bar(self):
        return 5

    @bar.setter
    def bar(self, a):
        print a

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return self.bar # --> recursion!

    @bar.setter
    def bar(self, c):
        # perform the same action
        # as in the base class
        self.bar = c    # --> recursion!
        # then do something else
        print 'something else'

fb = FooBar()
fb.bar = 7
هل كانت مفيدة؟

المحلول

قد تعتقد أنه يمكنك استدعاء وظيفة الفئة الأساسية التي يتم استدعاؤها بواسطة الخاصية:

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return Foo.bar(self)

على الرغم من أن هذا هو الشيء الأكثر وضوحًا الذي يجب تجربته، أعتقد - لا يعمل لأن الشريط خاصية، وليس قابلاً للاستدعاء.

لكن الخاصية هي مجرد كائن، مع طريقة getter للعثور على السمة المقابلة:

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return Foo.bar.fget(self)

نصائح أخرى

سوبر ينبغي أن تفعل خدعة:

return super().bar

في بيثون الإصدار 2.x تحتاج إلى استخدام بناء الجملة أكثر مطول:

return super(FooBar, self).bar

وهناك بديل باستخدام super التي لا تتطلب مرجع صراحة اسم الفئة الأساسية.

الفئة الأساسية A:

class A(object):
    def __init__(self):
        self._prop = None

    @property
    def prop(self):
        return self._prop

    @prop.setter
    def prop(self, value):
        self._prop = value

class B(A):
    # we want to extend prop here
    pass

في B، الوصول إلى جالبة ممتلكات الفئة الأصل A:

وأما البعض الآخر قد أجبت بالفعل، انها:

super(B, self).prop

وأو في بيثون 3:

super().prop

وهذا ما يعيد القيمة التي تم إرجاعها من قبل جالبة للممتلكات، وليس جالبة نفسها لكنه كاف لتمديد جالبة.

في B، والحصول على واضع الملكية من الفئة الأصل A:

وأفضل توصية رأيت حتى الآن هو ما يلي:

A.prop.fset(self, value)

وأعتقد أن هذا هو واحد أفضل:

super(B, self.__class__).prop.fset(self, value)

في هذا المثال كلا الخيارين تعادل ولكن باستخدام عظمى لديها ميزة كونها مستقلة عن الفئات الأساسية من B. إذا كانت B أن ترث من فئة C أيضا توسيع نطاق الملكية، لن يكون لكم لتحديث كود B ل.

كود كامل من B توسيع الملكية مصادر:

class B(A):
    @property
    def prop(self):
        value = super(B, self).prop
        # do something with / modify value here
        return value

    @prop.setter
    def prop(self, value):
        # do something with / modify value here
        super(B, self.__class__).prop.fset(self, value)

التحذير واحدة:

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

والمحاولة

@property
def bar:
    return super(FooBar, self).bar

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

هل يمكن تبديل دائما في بناء الجملة لاستخدام وظيفة الملكية () على الرغم من:

class Foo(object):

    def _getbar(self):
        return 5

    def _setbar(self, a):
        print a

    bar = property(_getbar, _setbar)

class FooBar(Foo):

    def _getbar(self):
        # return the same value
        # as in the base class
        return super(FooBar, self)._getbar()

    def bar(self, c):
        super(FooBar, self)._setbar(c)
        print "Something else"

    bar = property(_getbar, _setbar)

fb = FooBar()
fb.bar = 7
    class Base(object):
      def method(self):
        print "Base method was called"

    class Derived(Base):
      def method(self):
        super(Derived,self).method()
        print "Derived method was called"

    d = Derived()
    d.method()

و(أي ما أنا في عداد المفقودين شيء من تفسيركم)

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