为什么inspect.getsource不返回整个类的源代码?

0 投票
2 回答
964 浏览
提问于 2025-04-15 11:56

我在我的 forms.py 文件里有这段代码:

from django import forms
from formfieldset.forms import FieldsetMixin


class ContactForm(forms.Form, FieldsetMixin):
    full_name = forms.CharField(max_length=120)
    email = forms.EmailField()
    website = forms.URLField()
    message = forms.CharField(max_length=500, widget=forms.Textarea)
    send_notification = forms.BooleanField(required=False)

    fieldsets = ((u'Personal Information',
                {'fields': ('full_name', 'email', 'website'),
                'description': u'Your personal information will not ' \
                                u'be shared with 3rd parties.'}),
                (None,
                {'fields': ('message',),
                'description': u'All HTML will be stripped out.'}),
                (u'Preferences',
                {'fields': ('send_notification',)}))

当我尝试用 inspect 来提取代码时,它却漏掉了 fieldsets 这一部分:

In [1]: import inspect

In [2]: import forms

In [3]: print inspect.getsource(forms)
from django import forms
from formfieldset.forms import FieldsetMixin


class ContactForm(forms.Form, FieldsetMixin):
    full_name = forms.CharField(max_length=120)
    email = forms.EmailField()
    website = forms.URLField()
    message = forms.CharField(max_length=500, widget=forms.Textarea)
    send_notification = forms.BooleanField(required=False)

    fieldsets = ((u'Personal Information',
                {'fields': ('full_name', 'email', 'website'),
                'description': u'Your personal information will not ' \
                                u'be shared with 3rd parties.'}),
                (None,
                {'fields': ('message',),
                'description': u'All HTML will be stripped out.'}),
                (u'Preferences',
                {'fields': ('send_notification',)}))

In [4]: print inspect.getsource(forms.ContactForm)
class ContactForm(forms.Form, FieldsetMixin):
    full_name = forms.CharField(max_length=120)
    email = forms.EmailField()
    website = forms.URLField()
    message = forms.CharField(max_length=500, widget=forms.Textarea)
    send_notification = forms.BooleanField(required=False)


In [5]:      

这似乎不是因为空行的问题。我测试过没有空行的情况,也在其他属性之间加了空行,但结果没有变化。

有没有人知道为什么 inspect 只返回了 fieldsets 之前的部分,而不是整个类的源代码呢?

2 个回答

0

对我来说没问题。我代码里没有“from formfieldset.forms import FieldsetMixin”这一行。也许这就是导致问题的原因。

1

编辑:根据评论进行了修订:

inspect.getsource(forms.ContactForm) 这个代码里,使用了 BlockFinder.tokeneater() 方法来判断 ContactForm 这个块在哪里结束。它会检查一些东西,其中包括 tokenize.DEDENT,而这个在你存储在 GitHub 上的版本中正好出现在字段集之前。那一行只包含一个换行符,所以 inspect 认为当前的块已经结束了。

如果你插入4个空格,这样就能再次正常工作了。我不能解释这样做的原因,可能是出于性能考虑。

class ContactForm(forms.Form):
    full_name = forms.CharField(max_length=120)
    email = forms.EmailField()
    website = forms.URLField()
    message = forms.CharField(max_length=500, widget=forms.Textarea)
    send_notification = forms.BooleanField(required=False)
    # <-- insert 4 spaces here
    fieldsets = ((u'Personal Information',
                {'fields': ('full_name', 'email', 'website'),
                'description': u'Your personal information will not ' \
                                u'be shared with 3rd parties.'}),
                (None,
                {'fields': ('message',),
                'description': u'All HTML will be stripped out.'}),
                (u'Preferences',
                {'fields': ('send_notification',)}))

之所以 inspect.getsource(forms) 的表现不同,是因为在这种情况下,inspect 不需要判断类定义的开始和结束。它只是简单地输出整个文件。

撰写回答