python中关于类隐藏属性的三种处理方法
关于隐藏属性
引子:
当类的属性或者类实例对象的属性隐藏的时候必须通过存取器方法来获取和设置这些隐藏的属性。
例如:
def get_name(self,name): #存取器方法
self._name=name
通过外部调用实例函数传参达到获取和设置隐藏属性的目的。这样的函数叫做存取器
缺点:是必须通过调用存取器方法来实现这些功能
为此python提供了更强大的特性函数,即property函数
(1)property()函数
例如:
name=property(get_name,set_name)
property函数封装了get_name,set_name存取器方法,在类的外部可以像其他没隐藏的属性一样操作属性
实际上,property是一个类,它的实例包含了一些魔法方法,上述例子name=property()就是它的一个实例对象,这个实例对象实现了隐藏属性的反隐藏
property还可以通过修饰器的形式实现这个功能
(2)@property装饰器
实现其他语言所拥有的getter,setter和deleter的功能(例如IOS苹果开发,实现获取,设置,删除隐藏的属性)
作用:
用来模拟一个属性
(其实‘模拟’这个说法不是很准确,官方这么说就这么用了,应该说重写更合适,因为模拟前后的属性是同一个属性,用id()函数获取的地址值是相同的)
通过@property装饰器可以对模拟属性的取值和赋值加以控制
例如:
__双下划线隐藏的属性可以被控制在外部修改
@property (实现getter取值)
def score(self):
return self.__score 返回隐藏的属性
(score看似是一个实例函数,其实是一个属性,因为它已经被property装饰器装饰了)
@score.setter (实现设置值,必须写成setter,因为python就是这么规定的)
def score(self,v):
assert 0<=v<=100,‘成绩不合法’
self.__score=v
@score.deleter
def.score(self): (实现删除值)
del self.__socre
注意:
属性一旦删除,就无法设置和获取
为什么用properyt函数?
property通常用在类或者子类中对隐藏属性的改写,类的代码可能有几千行,隐藏属性在内部调用的次数可能就有几百次,如果一个个修改很麻烦,用存取器方法和property函数可以很方便的实现隐藏属性的反隐藏
另外python还有一种处理隐藏属性的方法,不过这个知识点比较晦涩难懂
(3)python的类内部有__getattr__,__setattr__,__delattr__魔法方法,能拦截所有的类属性
例如:
a.name
当在类的外部访问不到隐藏的属性时候,__getattr__会被自动调用,它搜索所的类属性,直到找到隐藏的属性
在类内__getattr__这些魔法方法是可以重写的(重写还是比较复杂的)
class A;
def __getattr__(self,name): #这里的形参name是属性名的意思,不是类属性self.name的那个name
if name=‘name’:
return self.__name
else:
raise AttributeError()
这里要写一个判断,目的是为了当找不到属性时候(类里面根本就没有这个属性,无论是否是隐藏的属性),就直接报错,避免__getattr__一直不停地搜寻下去,形成死循环
在交互模式下用help(list.__getattribute__)查看__getattr__或者__getattribute__的工作原理如下:
__getattribute__(self, name, /)
Return getattr(self, name)
它是返回python的内建函数getattr(),即不断地查询类内的所有属性
class A;
def __setattr__(self,name,value):
if name=‘name’:
self.__name=name
else:
self.__dict__[name]=value
这里设置判断,如果没有这个属性,就直接用__dict__[name]=name来给类实例增加一个属性,避免死循环
所以总结一下,用魔法方法__getattr__这类方法比用property属性方法相比更复杂点,建议处理同类问题的时候用property属性方法更好
python中关于类隐藏属性的三种处理方法的更多相关文章
- python 中增加css样式的三种方式
增加css样式的三种方式: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- Python 中删除列表元素的三种方法
列表基本上是 Python 中最常用的数据结构之一了,并且删除操作也是经常使用的. 那到底有哪些方法可以删除列表中的元素呢?这篇文章就来总结一下. 一共有三种方法,分别是 remove,pop 和 d ...
- DELPHI中的消息处理机制(三种消息处理方法的比较,如何截断消息)
DELPHI中的消息处理机制 Delphi是Borland公司提供的一种全新的WINDOWS编程开发工具.由于它采用了具有弹性的和可重用的面向对象Pascal(object-orientedpasca ...
- C++中的类继承(1) 三种继承方式
继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一.简单的说,继承是指一个对象直接使用另一对象的属性和方法.继承呈现了 面向对象程序设 计的层次结构, 体现了 由简单到复杂的认知过程. ...
- python中“*”、"*args"、"kwargs"三种用法
参考链接:https://www.cnblogs.com/cwind/p/8996000.html 注意的是: (1)"*"符号的用法很类似C++中的指针,针对列表; (2)&qu ...
- python中简单文件的输入三种方式
最近在自学python,简单的总结了一下文件的输入的方式. 1. f=open("foo.txt") line=f.readline() while line: print(lin ...
- python中自定义类对象json字符串化的方法
1. 用 json 或者simplejson 就可以 2.定义转换函数: def convert_to_builtin_type(obj): print 'default(', repr(obj), ...
- Class类对象的三种实例化方法
class X { } public class GetClassDemo01 { public static void main(String[] args) { X x = ...
- Python中的类、对象、继承
类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...
随机推荐
- 数据库之SqlDataAdapter
SqlDataAdapter 类 表示用于填充 DataSet 和更新 SQL Server 数据库的一组数据命令和一个数据库连接.无法继承此类. 命名空间:System.Data.SqlClient ...
- python实现线性排序算法-计数排序
计数排序假定输入元素的每一个都是介于0到k之间的整数,此处K为某个整数,当k=O(n)时,计数排序的运行时间为O(n) 它的基本思想是:根据每个输入元素x确定小于x的元素个数,根据这个信息把x直接放到 ...
- redis lru实现策略
转载自http://blog.chinaunix.net/uid-20708886-id-5753422.html 在使用redis作为缓存的场景下,内存淘汰策略决定的redis的内存使用效率.在大部 ...
- MySQL Workbench导出Model提示['ERROR 1064 (42000): You have an error in your SQL syntax....syntax to use near 'VISIBLE']
CREATE TABLE IF NOT EXISTS `pihealth`.`warning_events` ( `wid` INT NOT NULL AUTO_INCREMENT, `wtime` ...
- c++ vector的内存释放
c++中vector的一个特点是: 内存空间只会增长,不会减小.即为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都挨着前一个元素存储.设想,如果每次vector添加一个新元素 ...
- 学习之响应式Web设计---一个实例
周末闲来无事,做了一个响应式设计的例子.当然,由此并不能窥见响应式设计真谛之一斑.但,对于初次接触响应设计,对于响应式设计的概念依旧模糊不清的同学来说,或许是个启蒙! 闲语暂且不表,进入正题,这里没有 ...
- xlwt set style making error: More than 4094 XFs (styles)
使用Xlwt,当内容过多时,会报错:More than 4094 XFs (styles) 解决方法: wb = xlwt.Workbook(style_compression=2) 使用style_ ...
- listview监听组件内容变化
package com.meizu.ui.gifts; import android.app.Activity; import android.content.Context; import andr ...
- 这是一位拿到BAT大厂offer应届生的年终总结,那么你的呢?
壹 关于求职 2018年初,我还在北京后厂村的马路上被风吹得瑟瑟发抖. 那时我刚刚结束了半年的实习时光,开始考虑年后是否要继续实习.一开始我也在纠结实习转正和秋招之间如何权衡,但是在经历了春招以后,我 ...
- [git与github]__git与github简单了解
前言 关于版本控制,版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统. 我们通过版本控制系统可以解决的问题:可以非常方便的查看我们的源码文件的历代更新版本.或将我们的项目源 ...