我在的类中实现了只写属性@property
。奇怪的是,hasattr
具有此属性的类和相应实例的行为不同。
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
class User(Base, UserMixin):
# codes omitted...
@property
def password(self):
raise AttributeError("password is a write-only attribute!")
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
In [6]: hasattr(User,'password')
Out[6]: True
In [7]: u1=User()
In [9]: hasattr(u1,'password')
Out[9]: False
In [12]: getattr(User,'password')
Out[12]: <property at 0x1118a84a8>
In [13]: getattr(u1,'password')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-13-b1bb8901adc7> in <module>
----> 1 getattr(u1,'password')
~/workspace/python/flask_web_development/fisher/app/models.py in password(self)
82 @property
83 def password(self):
---> 84 raise AttributeError("password is a write-only attribute!")
85
86 @password.setter
AttributeError: password is a write-only attribute!
根据的结果getattr
,getattr(u1, 'password')
尝试执行该方法并引发错误,而getattr(User, 'password')
没有执行该@property
方法。他们为什么表现不同?
属性是描述符。
关于getattr
:
当您通过getattr
或对象(u1
)上的点符号访问属性,并且该对象()的类User
碰巧有一个您要访问的名称的描述符时,该描述符的__get__
方法称为1,就像您问题getattr(u1, 'password')
。在您的特定情况下,AttributeError
将执行您在getter中定义的逻辑(提高)。
随着getattr(User, 'password')
传递给该实例__get__
的方法是None
,在这种情况下,__get__
刚刚返回的描述符本身,而不是执行你实现吸气逻辑。
1有一些特殊的规则,取决于您是数据描述符还是非数据描述符,如描述符方法说明中所述。
关于hasattr
:
hasattr(u1, 'password')
返回,False
因为getattr(u1, 'password')
会引发错误。看到这个问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句