ITPub博客

首页 > 数据库 > 数据库开发技术 > python面向对象编程篇(3):@property装饰器一些用法

python面向对象编程篇(3):@property装饰器一些用法

原创 数据库开发技术 作者:程序员小钟同学 时间:2021-03-12 17:59:38 0 删除 编辑

本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。

个人其他博客地址:

简书:https://www.jianshu.com/u/d6960089b087

掘金:https://juejin.cn/user/2963939079225608

小钟同学 | 文 【原创】| QQ:308711822

1 .python中的@property装饰器

@property 在python是一个比较特殊的装饰器,不过本质上它也是一个函数,关于啥是装饰器。后面再补充说。

@property 使用的注意事项:

  • 被装饰方法有且只能有self一个参数,不能带上其他的参数

  • 调用被装饰方法的时候是不可以加括号,加了反而会报TypeError: 'Saiyaren1' object is not callable

@property装饰器的主要作用其实是把一个实例的方法,变成为一个实例的变量属性一样。 如下示例:

 #超级赛亚人形态1
class Saiyaren1():


    def eat(self):
        print('吃饭:我是超级赛亚人第1形态')
        return self


a = Saiyaren1()
a.eat()

对比加上@property上之后:

 #超级赛亚人形态1
class Saiyaren1():

    @property
    def eat(self):
        print('吃饭:我是超级赛亚人第1形态')
        return self


a = Saiyaren1()
a.eat

上面两个示例输出的结果都是:

 print('吃饭:我是超级赛亚人第1形态')

上面的主要区别是:

  • a.eat() 没有 @property装饰的时候需要加()
  • a.eat   @property装饰后不需要需要加()

property 其实是可以理解的我们的把一个函数里面涉及到所有的一些计算,转化为一个对象属性来调用。

2 .用property代替解决getter和setter方法

在一个类的封装中,通常我们的需要对一些内部的属性进行获取和设置,有可能设置的过程中需要进行一些了的运算后再返回的这个值。这个时候就比较有用: 如:

 #超级赛亚人形态1
class Saiyaren1():

    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self,new_name):
        if new_name == "赛亚人":
            self._name = "我是新的超级赛亚人"+new_name
        else:
            raise Exception("对不起您不是赛亚一族")


a = Saiyaren1("我是赛亚人")
print(a.name)
a.name="赛亚人"
print(a.name)
print('=========')
a.name="假冒伪劣赛亚人"

输出的结果为:

我是赛亚人
我是新的超级赛亚人赛亚人
Traceback (most recent call last):
=========
  File "D:/code/python/local_python/AntFlask/ceshi3.py", line 28, in <module>
    a.name="假冒伪劣赛亚人"
  File "D:/code/python/local_python/AntFlask/ceshi3.py", line 20, in name
    raise Exception("对不起您不是赛亚一族")
Exception: 对不起您不是赛亚一族

说明:@属性.setter也是一个函数,装饰后就可以控制属性的写入操作。

3 .特制私有属性和共有属性(隐藏不给外部人调用)

首先在Java,C++,以及PHP中都有使用对应的关键字:

  • public

public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用

  • private

private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。

  • protected

protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。

来定义声明类成员的访问作用域。就是约束我们的一些隐私变量如何保护。

再python中的话,则没有上面相关的明确的关键词来定义。

在python的定义了又一种约定俗成的方法:(但是在pyrhon其实上面哪些保护措施什么都是失效,无法彻底进行保护滴)

  • 以字母开头表示-public类型(可以被子类、类内以及类外被访问)
  • 以双下划线开头表示-private类型(只能是允许这个类本身进行访问了)
  • 以单下划线开头的表示的是-protected类型(只能允许其本身与子类进行访问)

PS:python中没有严格意义上的private类型。意思是,"虽然可以被访问,但是,请视为私有变量,不要随意访问。",这个是约定俗成的吧!

如示例:

class Saiyaren1():

    def __init__(self):
        # public
        self.name = "赛亚人"
        # private
        self.__age = 2923232
        # protected
        self._sex = "男"

    # public
    def fun1(self):
        print("公共方法")

    # private
    def __fun2(self):
        print("私有方法")

    # protected
    def _fun3(self):
        print("受保护方法")

a = Saiyaren1()
print('public',a.name)
print('protected',a._sex)
print('private',a.__age)

上面的代码是输出的时候: 到print('private',a.__age)的时候就会报错:

public 赛亚人
protected 男
Traceback (most recent call last):
  File "D:/code/python/local_python/AntFlask/ceshi3.py", line 30, in <module>
    print('private',a.__age)
AttributeError: 'Saiyaren1' object has no attribute '__age'

然后如果我坚持豪横的要调用的话也是有办法滴:

# 超级赛亚人形态1
class Saiyaren1():

    def __init__(self):
        # public
        self.name = "赛亚人"
        # private
        self.__age = 2923232
        # protected
        self._sex = "男"

    # public
    def fun1(self):
        print("公共方法")

    # private
    def __fun2(self):
        print("私有方法")

    # protected
    def _fun3(self):
        print("受保护方法")

a = Saiyaren1()
print('public',a.name)
print('protected',a._sex)
print('private',a._Saiyaren1__age)

就是这个:对象._类名__对象名

print('private',a._Saiyaren1__age)

PS:强烈建议不要这么干。

以上是个人对Python@property装饰器一些用法简要阐述。


End

纯属个人实践中相关经验阐述总结,如有纰漏,还希望大佬们多多提点!小钟同学 | 文  【原创】| QQ:308711822


原文作者:程序员小钟同学;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2021-02-20

  • 博文量
    224
  • 访问量
    111711