1 woshicai OP 自顶一记 没人不开心 |
![]() | 2 GreatMartial 2016-11-01 00:28:48 +08:00 via Android 不看你的代码,就看你的标题。 实例属性的查询方式是:先查询实例的属性,如果没有查询到,才会向类里查询相应的属性。 我是小白,可能说的不严谨。 这个知识点我是在博客园里,有一篇专门讲类与实例属性继承的文章里学习到的 |
![]() | 3 cheetah 2016-11-01 00:43:48 +08:00 这代码格式没法看啊 |
![]() | 4 Trim21 2016-11-01 00:52:04 +08:00 via Android 问题抽象了,同时把代码也抽象一下吧。。。 |
5 woshicai OP @GreatMartial 是啊 print(self)可以看到实例的属性是我初始化实例的数据 但是用 self.key 访问到的确实类的属性 @cheetah v 站貌似不支持 markdown @Trim21 好吧,把问题抽象一下。 简单的说就是我想获取 self 的属性, 用 self[key]能够正常获取我传入的数据, self.key 会出现异常(会返回类的 key 属性 default 值), print(self)显示实例的 key 值对应的是我传入的数据, 所以有疑惑。 想知道 self[key]和 self.key 的区别,为什么返回的结果不一样。 |
6 slideclick 2016-11-01 09:06:14 +08:00 self.key 是标准获得实例属性的 python 语法。除非实例里面没有,才会去读类级别变量。至于 self[key]为什么可以,那个是 Django 框架设计的,不是 python 语法 |
7 woshicai OP @slideclick 感谢解答。 尴尬的是我用的不是 Django 框架, 前面没说清楚, 我是让类 User 是继承 dict 类, 所以 self[key]的方式是可以的。 而且 print(self)打印出来的就是一个 dict : self: {'email': '[email protected]', 'name': 'Test1', 'image': 'about:blank', 'passwd': '1234567890'} |
8 focusheart 2016-11-01 10:24:49 +08:00 https://github.com/hfutcbl/python-liaoxuefeng_practice/blob/master/aiohttpPractice/orm.py 检查一下 orm.py 里对于 Model 类的构造: class Model(dict, metaclass=ModelMetaclass): def __init__(self, **kw): super(Model, self).__init__(**kw) 相当于调用的 dict 的构造, dict 的构造里没有将 key 直接转为 instance property 的默认行为吧?不过 ModelMetaclass 的__new__ 里可以处理吧。 另外,一般习惯上,对于这样使用 orm 的,用 instance[key] 的方式比较普遍吧。 |
9 woshicai OP @focusheart 非常感谢回答, 终于明白 self.key 为什么不行了。在 ModelMetaclass 的 __new__函数里没有确实没有将 key 处理为 instance property 。 但是还是有个问题:并不是所有 self.key 打印出来的值都是类中定义的 default 值,见输出: [email protected] <StringField, varchar(50):None> <StringField, varchar(50):None> <StringField, varchar(500):None> 还有个问题: 最初我是用 getattr(self, key, None) 来获取属性, class Model: ...... def __getattr__(self, key): try: return self[key] print('-------\n getattr() called \n-------------') ...... 发现 getattr 每次运行只被调用一次(我期待调用次数和 key 的个数一样),想知道 getattr 的调用顺序。 谢谢各位大神。 |
10 slideclick 2016-11-01 17:39:52 +08:00 __getattr__(self, name) Called only when an attempt to retrieve the named attribute fails, after the obj, Class and its superclasses are searched. The expressions obj.no_such_attr, get attr(obj, 'no_such_attr') and hasattr(obj, 'no_such_attr') may trigger Class.__getattr__(obj, 'no_such_attr'), but only if an attribute by that name cannot be found in obj or in Class and its superclasses. |