如何测试一个类是否包含特定属性?

3 投票
4 回答
3934 浏览
提问于 2025-04-15 21:59

我该怎么测试一个类里是否包含某个特定的属性呢?

In [14]: user = User.objects.get(pk=2)  

In [18]: user.__dict__  
Out[18]:   
{'date_joined': datetime.datetime(2010, 3, 17, 15, 20, 45),  
 'email': u'IloveDick@nwo.gov',  
 'first_name': u'',  
 'id': 2L,  
 'is_active': 1,  
 'is_staff': 0,  
 'is_superuser': 0,  
 'last_login': datetime.datetime(2010, 3, 17, 16, 15, 35),  
 'last_name': u'',  
 'password': u'sha1$44a2055f5',  
 'username': u'DickCheney'}  

In [25]: hasattr(user, 'username')  
Out[25]: True  

In [26]: hasattr(User, 'username')  
Out[26]: False  

我遇到了一个奇怪的bug,结果显示的属性比我实际定义的要多。我想有条件地停止这个情况。

比如说:

if not hasattr(User, 'karma'):
  User.add_to_class('karma', models.PositiveIntegerField(default=1)) 

4 个回答

1

User类没有用户名这个属性,因为模型的字段是在初始化时由元类添加的。不过,你可以通过使用Model._meta.get_field(filename)来检查一个模型是否定义了某个特定的字段。

7

我同意问题中关于EAFP(尽信则疑)的评论,但另一方面,有些情况下你需要采取LBYL(先看后跳)的方式。

对于Python类的一般方法在Django模型中不太适用,因为Django的元类魔法使得字段并不包含在模型类的__dict__中。所以,针对Django模型,你可以使用下面这样的函数:

def django_model_has_field(model_class, field_name):
    return field_name in model_class._meta.get_all_field_names()
9

据我所知,Django模型没有像hasattr()这样的检查方法。不过,有一种方法可以检查Django模型是否有某个字段。

为了测试这个,你可以打开Django的(Python)命令行工具:

$> python manage.py shell

接下来,导入用户模型:

$> from django.contrib.auth.models import User

获取模型的元信息:

$> opts = User._meta

要检查某个字段,可以使用以下命令:

$> opts.get_field('username')

如果是用户模型,系统会打印出类似这样的信息:

<django.db.models.fields.CharField object at 0x1024750>

如果你要查找的字段不在模型中,就会出现一个FieldDoesNotExist的错误。掌握了这些知识后,你就可以通过编程的方式检查字段是否存在了。

你可以在这里了解更多信息: b-list.org: Working with models

撰写回答