Python装饰器实现私有属性

1 Python装饰器实现私有属性

从装饰类的外部获取和修改指定属性,进行报错处理,允许类自身在其方法中访问和修改指定属性。

装饰类将私有属性传给装饰器入参,装饰器重载属性点号运算和赋值运算,来拦截属性访问和设置,若为私有属性则禁止访问和设置,通过委托的方式区分装饰类和装饰器的属性。

1.1 描述

使用装饰类入参存储私有属性列表,通过委托和__getattr__()、__setattr__()实现装饰类的属性访问和设置。

(1) 类装饰器最外层定义privateAttr函数,接收私有属性列表privates;

(2) 次外层定义onDecorator函数,接收装饰类;

(3) 次外层onDecorator函数主体,定义委托类onInstance,拦截装饰类的属性访问和设置;

(4) 将装饰类实例赋值给装饰器实例属性self.wrapped实现委托;

(5) 通过__getattr__()拦截未定义属性的点号运算,即装饰类属性;

(6) 通过__setattr__()拦截全部属性的赋值运算;

(7) 在私有属性列表内的属性,禁止访问和设置,进行抛错处理;

(8) 非私有属性访问通过getattr()转到装饰类实例上返回;

(9) 非私有属性设置通过setattr()转到装饰类实例上设置;

(10) 装饰器实例属性设置,通过self.__dict__[attr]=val设置,避免循环;

1.2 示例

>>> trace=False
>>> def traceCall(*args):#跟踪调用if trace:print('['+','.join(map(str,args))+']')>>> def privateAttr(*privates):#装饰器参数-私有属性列表def onDecorator(aCls):class OnInstance:def __init__(self,*args,**kargs):# 装饰类实例委托给装饰器self.wrapped=aCls(*args,**kargs)def __getattr__(self,attr):# 拦截非装饰器实例属性的访问# 即拦截装饰类的属性访问traceCall('getattr',attr)# 在私有属性列表则禁止访问if attr in privates:raise TypeError('禁止访问:'+attr)else:# 否则通过装饰类实例访问return getattr(self.wrapped,attr)def __setattr__(self,attr,value):# 拦截全部属性设置traceCall('setattr',attr,value)if attr=='wrapped':# 装饰器属性设置处理# __dict__ 避免循环设置属性self.__dict__[attr]=valueelif attr in privates:# 装饰类私有属性处理raise TypeError('禁止设置:'+attr)else:# 非私有属性通过装饰类实例设置属性setattr(self.wrapped,attr,value)return OnInstancereturn onDecorator>>> trace=True
>>> @privateAttr('data','size')
class Triple:def __init__(self,tag,beg):self.tag=tagself.data=begdef size(self):return len(self.data)def mul3(self):for i in range(self.size()):self.data[i]=self.data[i]*3def show(self):print(self.tag,' -> ',self.data)
# t1=Triple('t1 是',[9,5,55]) 执行过程
# 触发调用onDecorator()->调用 OnInstance(),
# 即触发 OnInstance 的构造函数 __init__()
# 触发self.wrapped赋值运算
# wrapped点号运算不触发 __getattr__(),因为是自身属性
# wrapped赋值运算触发 __setattr__()   
>>> t1=Triple('t1 是',[9,5,55])
[setattr,wrapped,<__main__.Triple object at 0x00000197322DE220>]
>>> t2=Triple('t2 是',[6,8,9])
[setattr,wrapped,<__main__.Triple object at 0x00000197322AF220>]
# t1.tag,t1.show,t1.mul3 装饰类属性触发 __getattr__()
# 非私有属性,通过装饰类实例访问
>>> print(t1.tag)
[getattr,tag]
t1 是
>>> t1.show()
[getattr,show]
t1 是  ->  [9, 5, 55]
>>> t1.mul3()
[getattr,mul3]
>>> t1.show()
[getattr,show]
t1 是  ->  [27, 15, 165]
>>> print(t2.tag)
[getattr,tag]
t2 是
>>> t2.show()
[getattr,show]
t2 是  ->  [6, 8, 9]
>>> t2.mul3()
[getattr,mul3]
>>> t2.show()
[getattr,show]
t2 是  ->  [18, 24, 27]
>>> t2.tag='梯阅线条'
[setattr,tag,梯阅线条]
>>> t2.show()
[getattr,show]
梯阅线条  ->  [18, 24, 27]
# size 和 data 私有属性,禁止访问和设置
>>> print(t1.size())
[getattr,size]
Traceback (most recent call last):File "<pyshell#66>", line 1, in <module>print(t1.size())File "<pyshell#51>", line 9, in __getattr__raise TypeError('禁止访问:'+attr)
TypeError: 禁止访问:size
>>> print(t1.data)
[getattr,data]
Traceback (most recent call last):File "<pyshell#67>", line 1, in <module>print(t1.data)File "<pyshell#51>", line 9, in __getattr__raise TypeError('禁止访问:'+attr)
TypeError: 禁止访问:data
>>> t1.data=[1,2,3]
[setattr,data,[1, 2, 3]]
Traceback (most recent call last):File "<pyshell#68>", line 1, in <module>t1.data=[1,2,3]File "<pyshell#51>", line 17, in __setattr__raise TypeError('禁止设置:'+attr)
TypeError: 禁止设置:data
>>> t1.size=lambda n:10
[setattr,size,<function <lambda> at 0x00000197322D1940>]
Traceback (most recent call last):File "<pyshell#69>", line 1, in <module>t1.size=lambda n:10File "<pyshell#51>", line 17, in __setattr__raise TypeError('禁止设置:'+attr)
TypeError: 禁止设置:size
>>> print(t2.data)
[getattr,data]
Traceback (most recent call last):File "<pyshell#70>", line 1, in <module>print(t2.data)File "<pyshell#51>", line 9, in __getattr__raise TypeError('禁止访问:'+attr)
TypeError: 禁止访问:data
>>> print(t2.size())
[getattr,size]
Traceback (most recent call last):File "<pyshell#71>", line 1, in <module>print(t2.size())File "<pyshell#51>", line 9, in __getattr__raise TypeError('禁止访问:'+attr)
TypeError: 禁止访问:size

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/619656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive数据定义(2)

hive数据定义是hive的基础知识&#xff0c;所包含的知识点有&#xff1a;数据仓库的创建、数据仓库的查询、数据仓库的修改、数据仓库的删除、表的创建、表的删除、内部表、外部表、分区表、桶表、表的修改、视图。在上一篇文章中介绍了一部分知识点&#xff0c;在本篇文章中将…

Vue2.脚手架

全局安装&#xff1a;npm i vue/cli -g检查是否成功安装&#xff1a;vue --version新建项目&#xff1a;vue create 项目名 通过nodejs安装的时候&#xff0c;可以直接代理和仓库&#xff0c;~/.npmrc文件内容如下&#xff1a; proxysocks5://127.0.0.1:7897 registryhttps:/…

解析流量新篇章:公域与私域共舞,探索2024商业未来

大家好我是模式策划啊浩Zeropan_HH。 嘿&#xff0c;伙伴们&#xff0c;你们好&#xff01;今天我想和大家聊聊2024年的商业趋势&#xff0c;特别是关于流量的那些事儿。 你们有没有觉得&#xff0c;现在的市场环境越来越复杂&#xff0c;流量的获取和运用成了每个企业发展的…

Kafka的核心原理

Topic的分区和副本机制 分区有什么用呢? 作用&#xff1a; 1- 避免单台服务器容量的限制: 每台服务器的磁盘存储空间是有上限。Topic分成多个Partition分区&#xff0c;可以避免单个Partition的数据大小过大&#xff0c;导致服务器无法存储。利用多台服务器的存储能力&#…

Matlab数学建模算法之模拟退火算法(SA)详解

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

WEB 3D技术 three.js 聚光灯

本文 我们来说说 点光源和聚光灯 点光源 就像一个电灯泡一样 想四周发散光 而聚光灯就像手电筒一样 像一个方向射过去 距离越远范围越大 光越弱 我们先来看一个聚光灯的效果 我们可以编写代码如下 import ./style.css import * as THREE from "three"; import { O…

【JavaScript】深度理解js的函数(function、Function)

简言 学了这么久的JavaScript&#xff0c;函数在JavaScript中最常用之一&#xff0c;如果你不会函数&#xff0c;你就不会JavaScript。 函数就是Function对象&#xff0c;一个函数是可以通过外部代码调用的一个“子程序”&#xff0c;它是头等&#xff08;first-class&#xf…

linux 如何创建文件

我们在写一些教程的时候&#xff0c;经常会需要创建一些用于演示的文档&#xff0c;这些文档往往需要填充一些不特定的内容。那么如何快速的创建演示用的文档呢&#xff1f; docfaker.py docfaker.py是一个py脚本&#xff0c;用于创建一个简单的txt文档&#xff0c;docfaker.…

getopt()函数详细解释!保证看明白

研究select模型的时候看到CSDN很多博主用到了getopt函数&#xff0c;这个模型弄的一脸懵&#xff0c;getopt先弄明白。。 getopt() 方法是用来分析命令行参数的&#xff0c;它的作用是判断你输入的命令行是否正确。 1.命令行组成 我们举例说明命令行组成 ls -l -a /etc 这…

ssh远程登陆

一、ssh远程登陆的概念 SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程 复制等功能。SSH 协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令&#xff0c;SSH 为建立在应用层…

MySQL 从零开始:06 数据检索

文章目录 1、数据准备2、限制结果3、完全限定名4、排序检索 所谓数据检索&#xff0c;就是前面所讲的”增删改查“的”查“。 注&#xff1a;本文使用的“行”指数据表中的“记录”&#xff0c;“列”指数据表中的“字段”。 在第四节《表的增删改查》中已经介绍了 select 查询…

Hive命令行运行SQL将数据保存到本地如何去除日志信息

1.场景分析 先有需求需要查询hive数仓数据并将结果保存到本地&#xff0c;但是在操作过程中总会有日志信息和表头信息一起保存到本地&#xff0c;不符合业务需要&#xff0c;那如何才能解决该问题呢&#xff1f; 废话不多少&#xff0c;直接上代码介绍&#xff1a; 2.问题解决…

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力…

计算机网络NCEPU复习资料

目录 一&#xff0e;概述&#xff1a; 计算机网络组成&#xff1a; 计算机网络分类&#xff1a; 计算机网络体系结构&#xff1a; C/S架构与P2P架构区别&#xff1a; OSI开放式系统互连参考模型&#xff1a; OSI开放式系统互连参考模型 相关协议&#xff1a; 五层协议网…

【python与物理】用类的形式设计U,R,I求解过程

class ElectricCircuit: def __init__(self, voltageNone, currentNone, resistanceNone):"""Args:voltage (float): 电压值&#xff0c;默认为None。current (float): 电流值&#xff0c;默认为None。resistance (float): 电阻值&#xff0c;默认为None。&quo…

Vue.js设计与实现阅读-3

Vue设计与实现阅读-3 1、声明式描述UI2、渲染器3、组件4、模板的工作原理5、Vue.js 是各个模块组成的有机整体 前言 前面一章我们了解了&#xff0c;开发体验是衡量一个框架的重要指标之一。提供友好的警告信息至关重要&#xff0c;但是越详细的警告信息&#xff0c;意味着框架…

5 微信小程序

功能开发 5 功能开发概要今日详细1.发布1.1 发布流程的问题1.2 组件&#xff1a;进度条1.3 修改data中的局部数据1.4 发布示例效果前端后端 1.5 闭包 2.获取前10条新闻&#xff08;动态/心情&#xff0c;无需分页&#xff09;3.复杂版4.文章详细页面 各位小伙伴想要博客相关资料…

华为OD机试2024年最新题库(C++)

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2024年1月-5月&#xff0c;考的都是OD统一考试&#xff08;C卷&#xff09;&#xff0c;题库已经整理…

【python入门】day26: 模拟高铁售票系统

界面 代码 #-*- coding:utf-8 -*- import prettytable as pt#---------导入漂亮表格 import os.path filename ticket.txt#更新座位状态 def update(row_num):#------更新购票状态with open(filename,w,encodingutf-8) as wfile:for i in range(row_num):lst1 [f{i1},有票,有…

Modbus协议学习第一篇之基础概念

什么是“协议” 大白话解释&#xff1a;协议是用来正确传递消息数据而设立的一种规则。传递消息的双方&#xff08;两台计算机&#xff09;在通信时遵循同一种协议&#xff0c;即可理解彼此传递的消息数据。 Modbus协议模型 Modbus协议模型较为简单&#xff0c;使用一种称为应用…