كيفية استدعاء خاصية الفئة الأساسية إذا تم الكتابة فوق هذه الخاصية في الفئة المشتقة؟
-
06-07-2019 - |
سؤال
أقوم بتغيير بعض الفئات الخاصة بي من الاستخدام المكثف للحروف والمستوطنين إلى استخدام أكثر بيثونية للخصائص.
لكنني الآن عالق لأن بعض الحروف أو أدوات الضبط السابقة كانت تستدعي الطريقة المقابلة للفئة الأساسية ثم تنفذ شيئًا آخر.ولكن كيف يمكن تحقيق ذلك مع الخصائص؟كيفية استدعاء حاصل الملكية أو واضعها في الفئة الأصل؟
بالطبع مجرد استدعاء السمة نفسها يعطي تكرارًا لا نهائيًا.
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()
و(أي ما أنا في عداد المفقودين شيء من تفسيركم)