بيثون التأمل: كيفية الحصول على قائمة "لم يتم فرزها" من سمات الكائن؟

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

سؤال

والتعليمة البرمجية التالية

import types
class A:
    class D:
        pass
    class C:
        pass
for d in dir(A):
    if type(eval('A.'+d)) is types.ClassType:
        print d

والمخرجات

C
D

وكيف يمكنني الحصول عليه لإخراج بالترتيب الذي تم تعريف هذه الفئات في مدونة؟ أي بمعنى.

D
C

هل هناك أي طريقة أخرى غير استخدام inspect.getsource (A)، وتحليل ذلك؟

هل كانت مفيدة؟

المحلول

ويضم وحدة inspect أيضا وظيفة findsource. تقوم بإرجاع الصفوف (tuple) خطوط المصدر ورقم السطر حيث يتم تعريف الكائن.

>>> import inspect
>>> import StringIO
>>> inspect.findsource(StringIO.StringIO)[1]
41
>>>

وظيفة findsource بالبحث في الواقع الحوض الصغير الملف المصدر وبالبحث عن المرشحين المحتملين إذا تم منحها فئة وجوه.

ونظرا لمن طريقة، فونكأيشن-، traceback-، frame-، أو رمز الكائن، يبدو ببساطة على السمة co_firstlineno من (الواردة) رمز الكائن.

نصائح أخرى

ملاحظة أن هذا التوزيع يتم بالفعل بالنسبة لك تفتيش في - نلقي نظرة على inspect.findsource، الذي يبحث في وحدة لتعريف الفئة وإرجاع عدد المصدر والخط. يجب أن يكون الترتيب على هذا العدد خط (قد تحتاج أيضا إلى تقسيم من فئات محددة في وحدات منفصلة) إعطاء حق النظام.

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

وثمة خيار آخر هو استخدام metaclasses، أو بطريقة أخرى ليأمر إما صراحة أو ضمنا المعلومات إلى كائن. على سبيل المثال:

import itertools, operator

next_id = itertools.count().next

class OrderedMeta(type):
    def __init__(cls, name, bases, dct):
        super(OrderedMeta, cls).__init__(name, bases, dct)
        cls._order = next_id()

# Set the default metaclass
__metaclass__ = OrderedMeta

class A:
    class D:
        pass
    class C:
        pass

print sorted([cls for cls in [getattr(A, name) for name in dir(A)] 
           if isinstance(cls, OrderedMeta)], key=operator.attrgetter("_order"))

ولكن هذا هو تغيير تدخلية إلى حد ما (يتطلب وضع metaclass من أي الطبقات كنت ترغب في أن OrderedMeta)

لا، لا يمكنك الحصول على تلك السمات في الترتيب الذي تبحث عنه. يتم تخزين سمات الثعبان في ديكت (اقرأ: hashmap)، الذي لا يوجد لديه الوعي أجل الإدراج.

وبالإضافة إلى ذلك، أود أن تجنب استخدام وحدة التقييم من قبل ببساطة قائلا

if type(getattr(A, d)) is types.ClassType:
    print d

في حلقة الخاص بك. لاحظ أنه يمكنك أيضا تكرار فقط من خلال أزواج مفتاح / قيمة في A.__dict__

وAFAIK، لا - ليس هناك *. وذلك لأن كل من سمات الفئة التي يتم تخزينها في القاموس (والذي هو، كما تعلمون، غير مرتبة).

*: أنه قد يكون في الواقع الممكن، ولكن هذا يتطلب إما الديكور أو ربما metaclass القرصنة. هل أي من تلك تهمك؟

وأنا لا أحاول أن أكون سطحي هنا، ولكن سيكون من الممكن بالنسبة لك لتنظيم الفئات في المصدر أبجديا؟ أجد أن عندما يكون هناك الكثير من الطبقات في ملف واحد وهذا يمكن أن تكون مفيدة في حد ذاتها.

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