美文网首页
property的使用

property的使用

作者: SimonJoe246 | 来源:发表于2018-12-07 22:11 被阅读0次

本质上说,本文提到的 @property 和上一篇文章提到的 @classmethod、@staticmethod 都是装饰器,都是对函数定义进行补充使之具有特殊功能。

正文

一、

设想:当我定义了一个用户类:

class User(Model):
    ...
    password = db.Column(db.String(64))
    ...

在上例中,很明显,password 是可以显式调用的属性,这在网站设计中绝不可以出现,会造成用户数据泄露的极大风险。那么,要将其变为私有属性,需要修改如下:

class User(Model):
    ...
    __password = db.Column(db.String(64))

这样,当创建实例变量后,再访问此属性会抛出 AttributeError 异常:

AttributeError: 'User' object has no attribute '__password'

这是一种解决办法,可是,当我们需要获取或者修改这个属性的值时,该怎么办呢?

只能通过为类增加实例方法来实现,方法中还可以加入参数检查的功能:

class User(Model):
    
    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def get_score(self):
        return self.__score

    def set_score(self, score):
    if 0 <= score <= 100:
        self.__score = score
    else:
        rasie ValueError('bad score')

但上面的方法略显复杂,python 提供了 @property 装饰器,可以轻松实现上述功能。

二、

创建一个只读属性:

class User(object):
    ...
    @property
    def score():
        return __score
    ...

使用 @property 可以将一个方法变为属性,无 @property 时,需要 u.score();使用之后,直接调用 u.score即可。

对于网站设计来说,常采用的做法是:将密码设置为只写属性,存储时,只存储其与其他用户属性生成的散列值(如用户密码+用户邮箱):

class User:
    
    @property
    def password(self):
        raise AttributeError('Password is not accessable.')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

当我们设置密码时,就可以使用 u.password = 'xxxx' 了。

在这个过程中,@property 又产生了另一个装饰器 @password.setter 将 password 方法变成属性赋值。

在 Python 的官方文档中,除了 gettersetter 外,还有一个 deleter

class User:
    
    @property
    def score():
        return __score

    @score.deleter
    def score(self):
        del score

顾名思义,这个派生出来的装饰器可以用来删除用户属性。

三、

在官方文档中,@property 装饰器还被这样使用:

class C:
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x

    def setx(self, value):
        self._x = value

    def delx(self):
        del self._x

    x = property(getx, setx, delx, "I'm the 'x' property.")

这样,u 是 C 的实例,当访问 u.x 时,将调用 u.getx() 方法。

u.x = value 将调用 u.setx(value) 方法。

del u.x 将调用 u.delx() 方法。

四、

@property 能将方法变成属性,又可在方法中加入参数检查的功能,这将它可普通属性区别开来,同时比定义额外的 get/set 方法清晰明了。将方法变成属性,这是 @property 的精髓。

参考链接


相关文章

  • Category添加成员变量

    类中使用@property @property (nonatomic,strong) NSString * nam...

  • iOS面试之@property

    原文链接 @property介绍 相信做过iOS开发的同学都使用过@property,@property翻译过来是...

  • @property的使用

    1.@proprety的作用 @property是编译器的指令 @proprety最初的最用是:用在声明文件中(....

  • @property的使用

    上次我们说到了构造方法,书接上文,这次我们来详细了解一下OC中@property中的内容.本文也是我自己寻找了相关...

  • property的使用

    本质上说,本文提到的 @property 和上一篇文章提到的 @classmethod、@staticmethod...

  • 使用property

    有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?Python内置的@property装饰器就是...

  • @property使用

    根据廖雪峰教程自己学习。 @property的使用简洁体现在:s1=Studnet() 赋值的时候直接用.属性名...

  • 使用 @property

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: 这显然不...

  • 使用@property

    使用@property:(首先,这个一般是放在类里边,其次这个放在类内函数之上) 既能检查参数(就是通过get()...

  • iOS开发中@property引伸的各种问题

    @property介绍 相信做过iOS开发的同学都使用过@property,@property翻译过来是属性。在定...

网友评论

      本文标题:property的使用

      本文链接:https://www.haomeiwen.com/subject/bctfhqtx.html