如何通过一些骚操作有效的控制Python类

平时工作中,能用到的类基本都是可变的,无论是实例的属性,还是类的属性,也正是因为这样,所以python也是一个“鸭子类型”的编程语言。

今天给大家看看python类的不同面,“不可变”

首先先来看下普通的类,我们都是怎么操作的

>>> class A:
...     pass
... 
>>> a = A()
>>> a.abc
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'A' object has no attribute 'abc'
>>> a.abc = 1
>>> a.abc
1

上面这段代码很简单,对于你来说一定也不陌生,在我们需要的时候动态的添加属性,这也是我们用python很爽的地方。

那么这个时候,如果这个类是个关键类,或者只是个只读类,如何才能组织这些动态的,不受控制的添加呢?

>>> class B:
...     __slots__ = ['papapa']
...     
...     def __init__(self, papapa):
...         super().__setattr__('papapa', papapa)
...         
...     def __setattr__(self, name, value):
...         raise AttributeError(f'{self.__class__} has no attribute {name}')
...     
>>> b = B('fanbingbing')
>>> b.papapa
'fanbingbing'
>>> b.papapa = 'linzhiling'
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 8, in __setattr__
AttributeError: <class 'B'> has no attribute papapa
>>> b.__dict__
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'B' object has no attribute '__dict__'
>>> b.abc = 123
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 8, in __setattr__
AttributeError: <class 'B'> has no attribute abc

这里的关键点有2个:

  1. __slots__ 方法,在类中,使用__slots__方法可以控制类的属性和方法,在定义完类后,我对b.__dict__做了一个查询,目的就是告诉大家,__slots__会替换掉__dict__,而__dict__就是类和实例存储属性的地方。 但是大家一定要注意,使用__slots__是有风险的,由于强制限制了__dict__的使用,那么你要添加任何方法和属性的时候就得重写这个类了,并且继承B类的子类,也需要重写__slots__方法。 所以通过__slots__,我们限制了实例属性的任意添加。
  2. __setattr__方法,我们在__init__这个构造函数中,添加了这个方法,目的是为了设置一个在__slots__中存在的属性的值,而在__setattr__函数中,我们重写了他,致使对任意类和实例属性进行修改的时候,都会进行异常抛出。 所以通过__setattr__,我们限制了实例属性“papapa”的任意修改。

如果对__slots__属性不理解的同学,推荐大家一个去处:

https://stackoverflow.com/questions/472000/usage-of-slots

写的很好。

如果你对今天的内容还感兴趣的话,何不点个赞再走呢?如果感兴趣到想赞赏我,就不要犹豫啦~


原文发布于微信公众号 - 猿媛牧场(xpchuiit)

原文发表时间:2018-06-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2102
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2667
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3065
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

25210
来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

3849
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2615
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏落花落雨不落叶

canvas画简单电路图

58811
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5267
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4798

扫码关注云+社区