前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >属性访问

属性访问

作者头像
天钧
发布2019-07-28 10:21:01
7180
发布2019-07-28 10:21:01
举报
文章被收录于专栏:渗透云笔记渗透云笔记

通常可以通过点(.)操作符的形式去访问对象的属性,关于属性的访问,也有相应的魔法方法来管理,

属性相关的魔法方法

魔法方法

含义

__getattr__(self,name)

定义当用户试图获取一个不存在的属性的行为

__getattribute__(self,name)

定义当该类的属性被访问时的行为

__setattr__(self,name,value)

定义当一个属性被设置时

__delattr__(self,name)

定义一个属性被删除时

例子

代码语言:javascript
复制
class C:    def __getattribute__(self,name):#当该类的属性被访问的行为        print('getattribute')        return super().__getattribute__(name)        def __setattr__(self,name,value):#当一个属性被设置时        print('setattr')        super().__setattr__(name,value)            def __delattr__(self,value):#当一个属性被删除        print('delattr')        super().__delattr__(name)            def __getattr__(self,name):#当用户获取一个不存在的上述属性        print('getattr')

运行后

代码语言:javascript
复制
>>> c = C()>>> c.xgetattributegetattr>>> c.x = 1setattr>>> c.xgetattribute1>>> del c.xdelattr

上面的几个魔法方法可能会造成死循环

看例子

要求;写一个矩形类(Rectangle),默认有宽和高两个属性,如果为一个叫做square的属性赋值,那么说明是个正方形,值就是正方形的边长,此时宽高都应等于边长

代码语言:javascript
复制
class Rectangle:    def __init__(self,width = 0,height = 0):        self.width = width        self.height = height    def __setattr__(self,name,value):        if name == 'square':            self.width = value            self.height = height        else:            self.name = value    def getArea(self):        return self.width * self.height

不妨粘在电脑里运行一下

分析原因,其实就是调用__init__时,不断地去触发__setattr__方法,造成了死循环

更改

代码语言:javascript
复制
class Rectangle:    def __init__(self,width = 0,height = 0):        self.width = width        self.height = height    def __setattr__(self,name,value):        if name == 'square':            self.width = value            self.height = height        else:            self.__dict__[name] = value    def getArea(self):        return self.width * self.height

运行

代码语言:javascript
复制
>>> r1 = Rectangle(4,5)>>> r1.getArea()20

迭代器

还记得迭代吗?

这篇介绍下

迭代类似于循环,每一次充分的过程被称为一次迭代

如序列(列表,元组,字符串),还有字典,都支持迭代操作

复习一下

代码语言:javascript
复制
>>> for i in 'tianjun':...     print(i)...tianjun>>>

字符串相当一个容器,也同时是个迭代器,for语句的作用介绍触发这个迭代器的迭代功能,每次拿出一个数据,就是迭代操作

关于迭代

Python有两个BIF

重点

iter()

next()

对一个容器对象调用iter就是得到他的接待器,调用next迭代器觉慧返回下一个值

如果一个容器是迭代器,那就必须调用iter方法,这个方法实际是就是返回迭代器本身,然后是实现的是next()魔法方法,因为它决定了迭代的规则,如下

用迭代器写的裴波那切数列:

代码语言:javascript
复制
class Fibs:      def __init__(self,n = 10):          self.a = 0          self.b = 1          self.n = n      def __iter__(self):         return self           def __next__(self):                 self.a,self.b = self.b,self.a+self.b         if self.a > self.n:             raise StopIteration         return self.a

生成器、什么是生成器

通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator

继续使用import sys斐波那契

代码语言:javascript
复制
 def fibonacci(n):     a, b, counter = 0, 1, 0    while True:        if (counter > n):             return        yield a        a, b = b, a + b        counter += 1f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True:    try:        print (next(f), end=" ")    except StopIteration:        sys.exit()

输出

代码语言:javascript
复制
0 1 1 2 3 5 8 13 21 34 55
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 渗透云笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档