三 __setattr__,__delattr__,__getattr__

__开头的都是内置的,不定义系统都会有。如果自己定义的话,就会覆盖系统内置的,执行自定义的部分(是否有完成设置的语法,有的话完成,没有就设置没成功,返回空字典)。可以通过dir(Foo)查看所有的内置属性。

用法:

三者的用法演示
class Foo:
x=1
def __init__(self,y):
self.y=y def __getattr__(self, item):
print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value):
print('----> from setattr')
# self.key=value #这就无限递归了,只要一出现设置值的操作,就会触发__init__函数,然后执行__setattr__.无限递归循环。
 # self.__dict__[key]=value #应该使用它 

def __delattr__(self, item): 

  print('----> from delattr') 

  # del self.item #无限递归了 
  self.__dict__.pop(item) #__setattr__添加/修改属性会触发它的执行 f1=Foo(10) print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值 f1.z=3 print(f1.__dict__) #__delattr__删除属性的时候会触发 f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作 del f1.a print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发 f1.xxxxxx
class Foo:
x=1
def __init__(self,y):
self.y=y def __setattr__(self, key, value):
print('__setattr__执行')
# self.key=value
self.__dict__[key]=value
f1=Foo(10)
print(f1.__dict__)
f1.z=2
print(f1.__dict__)
class Foo:
def __getattr__(self, item):
print('------------->') # print(Foo.__dict__)
print(dir(Foo))
f1=Foo() print(f1.x) #只有在属性不存在时,会自动触发__getattr__ del f1.x #删除属性时会触发_delattr__ f1.y=10
f1.x=3 # 设置属性的时候会触发——setattr———

利用__setattr__自定义把设置的属性都为字符串类型:
class Foo:
x=1
def __init__(self,y):
self.y=y def __setattr__(self, key, value):
print('__setattr__执行',key,value)
# self.key=value
if type(value) is str:
self.__dict__[key]=value.upper()#自定义全部转化为大写
else:
print('【%s】不是字符串类型' %value)
f1=Foo('alex')
print(f1.__dict__)
f1.z=2
print(f1.__dict__)

四 二次加工标准类型(包装)

包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工。

派生:继承原来的基本属性,并且派生出新的属性规则。

#利用继承派生来定制化函数
class List(list):
def append(self, p_object):
if type(p_object) is str: #定制只能添加为字符串的函数
#self.append(p_object) 无限死循环,解决方法调用父类
super().append(p_object)
else:
print('只能添加字符串')
def show_middle(self): #定制之获取中间的元素的函数。
i=int(len(self)/2)
return self[i-1] l1=List('helloworld')#没写实例化函数,继承list的实例化过程。
#相当于在执行:l2=list(hello world)
print(l1,type(l1))
print(l1)
l1.append('sd')
print(l1)
print(l1.show_middle())
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] <class '__main__.List'>
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', 'sd']
o

答案

授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__getattr__方法


day26:面向对象进阶:set、get、del反射和内置的更多相关文章

  1. python 面向对象之反射及内置方法

    面向对象之反射及内置方法 一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静 ...

  2. 面向对象(五)——isinstance与issubclass、反射、内置方法

    isinstance与issubclass.反射.内置方法 一.isinstance与issubclass方法 1.isinstance是用来判断对象是否是某个类 isinstance(obj,cla ...

  3. Python反射和内置方法(双下方法)

    Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...

  4. day26.面向对象-反射封装内置方法

    封装 隐藏对象的属性和实现细节,近对外提供公共访问方式 广义:代码保护,面向对象思想 狭义:将属性,方法隐藏起来 class Person: __key = 123456 # 私有的静态属性 def ...

  5. day28 面向对象:反射,内置函数,类的内置方法

    面向对象进阶博客地址链接: http://www.cnblogs.com/Eva-J/articles/7351812.html 复习昨日内容: # 包 # 开发规范 # # hashlib # 登录 ...

  6. Python之路(第二十五篇) 面向对象初级:反射、内置方法

    [TOC] 一.反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它 ...

  7. 面向对象(五)--isinstance与issubclass方法、反射、内置方法(部分)、异常处理

    一.isinstance与issubclass方法 1.isinstance是用来判断对象是否是某个类 isinstance(obj,class) 2.issubclass是用来判断一个类是否为另一个 ...

  8. 反射与内置方法str del

    1.反射 用字符串来操作类或者对象的属性 class People:# country= 'china'# def __init__(self,name):# self.name= name## de ...

  9. python面向对象 : 反射和内置方法

    一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类  (注:type(对象名) is 类名 : 判断对象所属 ...

随机推荐

  1. 【转】Thread.isBackground

    C#中,Thread类有一个IsBackground 的属性.MSDN上对它的解释是:获取或设置一个值,该值指示某个线程是否为后台线程.个人感觉这样的解释等于没有解释. .Net中的线程,可以分为后台 ...

  2. 关于IE9-解决background-size的问题

    body{background:url("/branch/comm/images-new/login.jpg") no-repeat;background-size:100%;fi ...

  3. ubuntu下avd创建和文件传输

    进入安卓官网下载安卓sdk并解压到指定路径 在命令行模式下进入安卓文件的toos文件夹下 android avd #在弹出的对话框中新建虚拟机 adb install ~/targetPath/hel ...

  4. win10 64位 mysql安装

    一.安装mysql 1.下载mysql-5.7.15-winx64.zip http://dev.mysql.com/downloads/mysql/ 2.解压缩到D:\ProgramFiles 3. ...

  5. span标签跳转新页面

      <span onclick="javascript:window.open('http://eccu.fr/guanli/login.aspx')" style=&quo ...

  6. Mac、Linux更换命令行svn diff为P4Merge、vimdiff

    2015-01-21 21:25:52 这里先把那个程序员大神的博客地址贴一下(PS:大神,我不是为了抄袭哦,真是怕自己忘记了),http://www.ccvita.com/445.html,里面还有 ...

  7. DirectShow开发快速入门之慨述

    摘要:本篇文档概括性的介绍了DirectShow的主要组成部分,以及一些Directshow的基本概念.熟悉这些基本的知识对于Directshow的应用开发或者过滤器的开发者都会有所帮助. Direc ...

  8. shell命令

    1:操作系统:人--使用-->shell(或应用程序)--呼叫-->kernel(核心)--->硬件2:查看shell的种类:# cat /etc/shells3:而这个登入系统的 ...

  9. Codeforces Round #325 (Div. 2) D bfs

    D. Phillip and Trains time limit per test 1 second memory limit per test 256 megabytes input standar ...

  10. Clojure web初探

    项目环境:3.2.0-52-generic #78-Ubuntu SMP Fri Jul 26 16:21:44 UTC 2013 x86_64 x86_64 x86_64 GNU/LinuxLein ...