NJU1healer的个人博客分享 http://blog.sciencenet.cn/u/NJU1healer

博文

Python中@property详解

已有 2358 次阅读 2020-8-28 19:44 |个人分类:Python|系统分类:科研笔记

1. 作用

       将类方法转换为类属性,可以用 . 直接获取属性值或者对属性进行赋值!

2.实现方式

       使用property类来实现,也可以使用property装饰器实现,二者本质是一样的。多数情况下用装饰器实现。

class Student(object):
    @property
    def score(self):
        return self._score
    @score.setter
    def score(self, value):
        if not isinstance(value ,int):
            raise ValueError('分数必须是整数')
        if value <0 or value>100:
            raise ValueError('分数必须0-100之间')
        self._score = value
student = Student()
student.score = 65
print(student.score)
65

       score()方法上增加@property装饰器,等同于score= property(fget=score),将score赋值为property的实例。

       所以,被装饰后的score,已经不是这个实例方法score了,而是property的实例score。

3.具体实例真正理解@property

       有没有可以用类似属性这样简单的方式来访问类的变量呢?必须的,对于类的方法,看看@property的妙用之处!

class Person(object):

     def __init__(self, name, age):

         self.__name = name

         self.__age = age

  

     @property

     def get_age_fun(self):

           return self.__age

  

     @get_age_fun.setter 

     # get_age_fun是上面声明的方法,若没这句,set_age_fun的操作对于get_age_fun无用!

     def set_age_fun(self, value):

         if not isinstance(value, int):

             raise ValueError('年龄必须是数字!')

         if value < 0 or value > 100:

             raise ValueError('年龄必须是0-100')

         self.__age = value

 

     def print_info(self):

         print('%s: %s' % (self.__name, self.__age))

 

 

p = Person('balala',20)

p.__age = 17

print(p.__age) # 17

print(p.get_age_fun) # 20 注意这里不带()

 

 #p.set_age_fun(35) 注意不能这样调用赋值了

p.set_age_fun = 35 #  这里set_age_fun 就是 声明的函数不带()

print(p.get_age_fun) # 35

print(p.print_info()) # balala: 35


接下来,我们从最初的开始说起

(1)我们先看个详细的例子(注意双下划线name和age定义为私有变量):

class Person(object):

    def __init__(self, name, age):

        self.__name = name

        self.__age = age


    def get_age_fun(self):

         return self.__age


    def set_age_fun(self, value):

        if not isinstance(value, int):

            raise ValueError('年龄必须是数字!')

        if value < 0 or value > 100:

            raise ValueError('年龄必须是0-100')

        self.__age = value


    def print_info(self):

        print('%s: %s' % (self.__name, self.__age))



p = Person('balala',20)

p.__age = 17

print(p.__age) # 17

print(p.get_age_fun()) # 20 表面上看,上面代码“成功”地设置了__age变量 17,但实际上这个__age变量和class内部的__age变量不是一个变量!

# 内部的__age变量已经被Python解释器自动改成了_Person_age,而外部代码给p新增了一个__age变量。 所以调用 get_age_fun输出的是初始值


p.set_age_fun(35)

print(p.get_age_fun()) # 35


print(p.print_info()) # balala: 35

(2)我们接着进行进一步调整

(注意只改变了一个变量名: 原来的私有属性 __age 单下划线为: _age,也可以定义为:age. 

解释:以一个下划线开头的实例变量名,比如_age,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当看到这样的变量时,意思是,"虽然可以被访问,但是,请视为私有变量,不要随意访问。")

class Person(object):

    def __init__(self, name, age):

        self.__name = name

        self._age = age


    def get_age_fun(self):

         return self._age


    def set_age_fun(self, value):

        if not isinstance(value, int):

            raise ValueError('年龄必须是数字!')

        if value < 0 or value > 100:

            raise ValueError('年龄必须是0-100')

        self._age = value


    def print_info(self):

        print('%s: %s' % (self.__name, self._age))



p = Person('balala',20)

p._age = 17

print(p._age) # 17

print(p.get_age_fun()) # 这里是17 不再是 20,因为此时_age是全局变量,外部直接影响到类内部的更新值


p.set_age_fun(35)

print(p.get_age_fun()) # 35


print(p.print_info()) # balala: 35

点滴分享,福泽你我!Add oil!

【参考】

https://www.cnblogs.com/bob-coder/p/11532718.html

https://www.cnblogs.com/phpper/p/10618775.html




https://wap.sciencenet.cn/blog-3428464-1248300.html

上一篇:Pip更新问题解决及Jupyter实现所选变量高亮显示和分区注释
下一篇:Python:loc和iloc的区别
收藏 IP: 211.162.81.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-29 23:04

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部