كيف يمكنني استنتاج الفصل الذي ينتمي إليهstaticmethod؟
-
09-09-2019 - |
سؤال
أحاول التنفيذ infer_class
وظيفة ذلك، إعطاء طريقة، أرقام الفصل الذي تنتمي إليه الطريقة.
حتى الآن لدي شيء مثل هذا:
import inspect
def infer_class(f):
if inspect.ismethod(f):
return f.im_self if f.im_class == type else f.im_class
# elif ... what about staticmethod-s?
else:
raise TypeError("Can't infer the class of %r" % f)
لا يعمل من أجل staticmethod-s لأنني لم أتمكن من التوصل إلى طريقة لتحقيق ذلك.
أي اقتراحات؟
هنا infer_class
في العمل:
>>> class Wolf(object):
... @classmethod
... def huff(cls, a, b, c):
... pass
... def snarl(self):
... pass
... @staticmethod
... def puff(k,l, m):
... pass
...
>>> print infer_class(Wolf.huff)
<class '__main__.Wolf'>
>>> print infer_class(Wolf().huff)
<class '__main__.Wolf'>
>>> print infer_class(Wolf.snarl)
<class '__main__.Wolf'>
>>> print infer_class(Wolf().snarl)
<class '__main__.Wolf'>
>>> print infer_class(Wolf.puff)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in infer_class
TypeError: Can't infer the class of <function puff at ...>
المحلول
ذلك لأن staticmethods حقا ليست أساليب. واصف staticmethod إرجاع الوظيفة الأصلية كما هو. لا توجد وسيلة للحصول على الفصل الذي تم الوصول إليه من خلال الوظيفة. ولكن ليس هناك سبب حقيقي لاستخدام StaticMethods للأساليب على أي حال، استخدم دائما ClassMethods.
الاستخدام الوحيد الذي وجدته بحثا عن StaticMethods هو تخزين كائنات الوظيفة كسمات فئة وليس لها أن تتحول إلى الأساليب.
نصائح أخرى
لدي مشكلة في جلب نفسي في الواقع نوصي هذا، لكن يبدو أنه يعمل من أجل الحالات المباشرة، على الأقل:
import inspect
def crack_staticmethod(sm):
"""
Returns (class, attribute name) for `sm` if `sm` is a
@staticmethod.
"""
mod = inspect.getmodule(sm)
for classname in dir(mod):
cls = getattr(mod, classname, None)
if cls is not None:
try:
ca = inspect.classify_class_attrs(cls)
for attribute in ca:
o = attribute.object
if isinstance(o, staticmethod) and getattr(cls, sm.__name__) == sm:
return (cls, sm.__name__)
except AttributeError:
pass
لا تنتمي إلى StackOverflow