एक परिशिष्ट:
आप माता-पिता कक्षा में __test__ = False
सेट कर सकते हैं और फिर जब उपवर्गीकरण सच में पुन: स्थापित करने के लिए एक metaclass (कुछ प्रतिभाशाली स्पष्टीकरण के साथ This question देखें) का उपयोग करें।
(अंत में, मैं एक बहाना एक metaclass उपयोग करने के लिए मिल गया!)
हालांकि __test__
एक डबल अंडरस्कोर विशेषता है, हम स्पष्ट रूप से, True
के लिए सेट की स्थापना नहीं के बाद से यह सिर्फ देखने के लिए अजगर का कारण होगा करने के लिए है विशेषता MRO को आगे बढ़ाएं और इसे False
पर मूल्यांकन करें।
इस प्रकार, हमें क्लास इंस्टेंटेशन पर जांच करने की आवश्यकता है कि क्या माता-पिता वर्गों में से एक __test__ = False
है। यदि यह मामला है और वर्तमान श्रेणी परिभाषा ने __test__
स्वयं सेट नहीं किया है, तो हम गुणों के लिए '__test__': True
जोड़ देंगे।
class TestWhenSubclassedMeta(type):
"""Metaclass that sets `__test__` back to `True` when subclassed.
Usage:
>>> class GenericTestCase(TestCase, metaclass=TestWhenSubclassed):
... __test__ = False
...
... def test_something(self):
... self.fail("This test is executed in a subclass, only.")
...
...
>>> class SpecificTestCase(GenericTestCase):
... pass
"""
def __new__(mcs, name, bases, attrs):
ATTR_NAME = '__test__'
VALUE_TO_RESET = False
RESET_VALUE = True
values = [getattr(base, ATTR_NAME) for base in bases
if hasattr(base, ATTR_NAME)]
# only reset if the first attribute is `VALUE_TO_RESET`
try:
first_value = values[0]
except IndexError:
pass
else:
if first_value == VALUE_TO_RESET and ATTR_NAME not in attrs:
attrs[ATTR_NAME] = RESET_VALUE
return super().__new__(mcs, name, bases, attrs)
एक तरह "अगर नाम Abstract
साथ शुरू होता है, __test__ = False
स्वचालित रूप से सेट" कुछ और अंतर्निहित व्यवहार को यह विस्तार सकता है, लेकिन मैं अपने आप को स्पष्ट काम रखना होगा:
जिसके परिणामस्वरूप कोड इस तरह दिखता है विस्तृत जानकारी के लिए।
मुझे व्यवहार प्रदर्शित करने के लिए सरल unittests पेस्ट करते हैं - और एक चेतावनी के रूप में सभी एक सुविधा शुरू करने के बाद अपने कोड का परीक्षण करने के लिए दो मिनट का समय चाहिए।
from unittest import TestCase
from .base import TestWhenSubclassedMeta
class SubclassesTestCase(TestCase):
def test_subclass_resetted(self):
class Base(metaclass=TestWhenSubclassedMeta):
__test__ = False
class C(Base):
pass
self.assertTrue(C.__test__)
self.assertIn('__test__', C.__dict__)
def test_subclass_not_resetted(self):
class Base(metaclass=TestWhenSubclassedMeta):
__test__ = True
class C(Base):
pass
self.assertTrue(C.__test__)
self.assertNotIn('__test__', C.__dict__)
def test_subclass_attr_not_set(self):
class Base(metaclass=TestWhenSubclassedMeta):
pass
class C(Base):
pass
with self.assertRaises(AttributeError):
getattr(C, '__test__')
'__test__ = FALSE' चाल बहुत उपयोगी नहीं है एक माता पिता के वर्ग के मामले में, यह बच्चों को स्पष्ट रूप से निर्दिष्ट करने के लिए मजबूर होना पड़ा कक्षाएं' __test__ = TRUE' या यह नजरअंदाज कर दिया जाएगा, जो एक खतरनाक है उपयोग करने के लिए चाल। – Guibod