इस साल देर से की एक जोड़ी है, लेकिन यहाँ है जिस तरह से मैंने किया: अगर C
MetaClass
का एक प्रयास किया वर्ग है
import abc
class MetaClass(object):
__metaclass__ = abc.ABCMeta
[...]
@classmethod
def __subclasshook__(cls, C):
if C.__abstractmethods__:
print C.__abstractmethods__
return False
else:
return True
, तो C.__abstractmethods__
खाली ही हो जाएगा यदि C
सभी अमूर्त तरीकों को लागू करता है।
जानकारी के लिए यहाँ देखें: https://www.python.org/dev/peps/pep-3119/#the-abc-module-an-abc-support-framework (यह "कार्यान्वयन" के अंतर्गत है, लेकिन __abstractmethods__
के लिए एक खोज सही अनुच्छेद पर आप मिलना चाहिए)
कहाँ यह मेरे लिए काम किया है:
मैं MetaClass
बना सकते हैं। मैं SubClass
बनाने के लिए BaseClass
और MetaClass
उपclass कर सकता हूं जिसके लिए कुछ अतिरिक्त कार्यक्षमता की आवश्यकता है।लेकिन मुझे BaseClass
विशेषता को बदलकर पर एक उदाहरण डालने की आवश्यकता है क्योंकि मेरे पास BaseClass
नहीं है, लेकिन मुझे इसके उदाहरण मिलते हैं जिन्हें मैं नीचे डालना चाहता हूं।
हालांकि, अगर मैं अनुचित तरीके से SubClass
लागू, मैं अभी भी नीचे डाल सकता जब तक कि मैंने ऊपर __subclasshook__
का उपयोग करें और बस एक उपवर्ग जांच जोड़ने जब मैं प्रक्रिया नीचे डाली (जो मैं वैसे भी क्या करना चाहिए के बाद से मैं केवल कास्ट करने के लिए कोशिश करना चाहते हैं एक अभिभावक वर्ग नीचे)। अगर कोई अनुरोध करता है, तो मैं इसके लिए एक MWE प्रदान कर सकता हूं।
ईटीए: यहां एक MWE है। मुझे लगता है कि मैं पहले जो सुझाव दे रहा था वह गलत था, इसलिए मेरा इरादा ऐसा करने लगता है।
लक्ष्य BaseClass
ऑब्जेक्ट को SubClass
और वापस कनवर्ट करने में सक्षम होना है। SubClass
से BaseClass
से आसान है। लेकिन BaseClass
से SubClass
से बहुत कुछ नहीं। करने के लिए मानक बात __class__
विशेषता अद्यतन है, लेकिन SubClass
वास्तव में उप-वर्ग नहीं है या एक अमूर्त मेटा वर्ग से प्राप्त नहीं होता है, लेकिन यह ठीक से कार्यान्वित नहीं किया जाता है।
नीचे, रूपांतरण convert
विधि में किया गया है जो BaseMetaClass
लागू करता है। हालांकि, उस तर्क में, मैं दो चीजों की जांच करता हूं। एक, सबक्लास में कनवर्ट करने के लिए, मैं जांचता हूं कि यह वास्तव में उप-वर्ग है या नहीं। दूसरा, यह देखने के लिए कि क्या यह खाली है, मैं विशेषता __abstractmethods__
विशेषता की जांच करता हूं। यदि यह है, तो यह भी एक उचित ढंग से लागू मेटाक्लास है। विफलता टाइप टाइपर की ओर ले जाती है। अन्यथा वस्तु परिवर्तित हो जाती है।
import abc
class BaseMetaClass(object):
__metaclass__ = abc.ABCMeta
@classmethod
@abc.abstractmethod
def convert(cls, obj):
if issubclass(cls, type(obj)):
if cls.__abstractmethods__:
msg = (
'{0} not a proper subclass of BaseMetaClass: '
'missing method(s)\n\t'
).format(
cls.__name__
)
mthd_list = ',\n\t'.join(
map(
lambda s: cls.__name__ + '.' + s,
sorted(cls.__abstractmethods__)
)
)
raise TypeError(msg + mthd_list)
else:
obj.__class__ = cls
return obj
else:
msg = '{0} not subclass of {1}'.format(
cls.__name__,
type(obj).__name__
)
raise TypeError(msg)
@abc.abstractmethod
def abstractmethod(self):
return
class BaseClass(object):
def __init__(self, x):
self.x = x
def __str__(self):
s0 = "BaseClass:\n"
s1 = "x: {0}".format(self.x)
return s0 + s1
class AnotherBaseClass(object):
def __init__(self, z):
self.z = z
def __str__(self):
s0 = "AnotherBaseClass:\n"
s1 = "z: {0}".format(self.z)
return s0 + s1
class GoodSubClass(BaseMetaClass, BaseClass):
def __init__(self, x, y):
super(GoodSubClass, self).__init__(x)
self.y = y
@classmethod
def convert(cls, obj, y):
super(GoodSubClass, cls).convert(obj)
obj.y = y
def to_base(self):
return BaseClass(self.x)
def abstractmethod(self):
print "This is the abstract method"
def __str__(self):
s0 = "SubClass:\n"
s1 = "x: {0}\n".format(self.x)
s2 = "y: {0}".format(self.y)
return s0 + s1 + s2
class BadSubClass(BaseMetaClass, BaseClass):
def __init__(self, x, y):
super(BadSubClass, self).__init__(x)
self.y = y
@classmethod
def convert(cls, obj, y):
super(BadSubClass, cls).convert(obj)
obj.y = y
def __str__(self):
s0 = "SubClass:\n"
s1 = "x: {0}\n".format(self.x)
s2 = "y: {0}".format(self.y)
return s0 + s1 + s2
base1 = BaseClass(1)
print "BaseClass instance"
print base1
print
GoodSubClass.convert(base1, 2)
print "Successfully casting BaseClass to GoodSubClass"
print base1
print
print "Cannot cast BaseClass to BadSubClass"
base1 = BaseClass(1)
try:
BadSubClass.convert(base1, 2)
except TypeError as e:
print "TypeError: {0}".format(e.message)
print
print "Cannot cast AnotherBaseCelass to GoodSubClass"
anotherbase = AnotherBaseClass(5)
try:
GoodSubClass.convert(anotherbase, 2)
except TypeError as e:
print "TypeError: {0}".format(e.message)
print
print "Cannot cast AnotherBaseCelass to BadSubClass"
anotherbase = AnotherBaseClass(5)
try:
BadSubClass.convert(anotherbase, 2)
except TypeError as e:
print "TypeError: {0}".format(e.message)
print
# BaseClass instance
# BaseClass:
# x: 1
# Successfully casting BaseClass to GoodSubClass
# SubClass:
# x: 1
# y: 2
# Cannot cast BaseClass to BadSubClass
# TypeError: BadSubClass not a proper subclass of BaseMetaClass: missing method(s)
# BadSubClass.abstractmethod
# Cannot cast AnotherBaseCelass to GoodSubClass
# TypeError: GoodSubClass not subclass of AnotherBaseClass
# Cannot cast AnotherBaseCelass to BadSubClass
# TypeError: BadSubClass not subclass of AnotherBaseClass
'नहीं, मैं इस परियोजना में इंटरफेस का उपयोग नहीं कर सकता।' क्यों? (मैं व्यंग्यात्मक नहीं हूं; वास्तव में उत्सुकता क्या उपयोग केस हो सकता है) –