Python实例属性限制(__slots__)
Python的动态绑定可以在程序运行的过程中对实例或class加上功能,但是如果我们想要限制实例的属性怎么办呢?更改内容请参考:Python学习指南
正常情况下,当我们定义了一个class,创建了一个class实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。先定义class:
class Student(object):
pass
然后,尝试给实例绑定一个属性:
s = Student()
s.name = 'Michael'
print(s.name)
Michael
还可以给实例绑定一个方法:
def set_age(self, age): #定义一个函数作为实例方法
self.age = age
from types import MethodType
s.set_age = MethodType(set_age, s) #给实例绑定一个方法
s.set_age(25)
s.age
25
但是,给一个实例绑定的方法,对另一个实例是不起作用的:
s2 = Student() #创建一个新的实例
s2.set_age(25)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'set_age'
为了给所有实例都绑定方法,可以给class绑定方法:
def set_score(self, score):
self.score = score
Student.set_score = set_score
给class绑定方法后,所有实例均可调用:
s.set_score(100)
s.score
100
s2.set_score(99)
s2.score
99
只要在class上绑定方法以后,实例就可以直接使用了。
通常情况下,上面的set_score方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。
使用__slots__
但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age实现。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的变量__slots__变量,来限制该class实例能添加的属性:
class Student(object):
__slots__ = ('name', 'age') #用tuple定义允许绑定的属性名称
然后,我们试试:
>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
>>>Student.score = 100
>>>s.score
100
由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。但是可以对class类添加属性,__slots__只是限制实例添加的属性,但类属性管不了。
使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
class GraduteStudent(Student):
pass
g = GraduteStudent()
s.score = 99
除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
Python实例属性限制(__slots__)的更多相关文章
- python:实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(object): def __init__(se ...
- python 实例属性
>>> class a(object): pass >>> o=a() >>> o.a='ok'#直接给实例添加属性,调用了__setattri_ ...
- python 实例属性之单,双下划线
具体区别看下面例子 class A: def __init__(self,name='Andy'): self._name = name class B: def __init__(self,name ...
- python基础——实例属性和类属性
python基础——实例属性和类属性 由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(objec ...
- Python之实例属性和类属性
参考原文 廖雪峰Python 实例属性和类属性 在前面已经说过由于Python是动态语言,可以根据类的实例绑定任何的属性. 给实例绑定属性的方法是通过实例变量,或者self变量绑定的: class S ...
- Python笔记(十八)_私有属性、实例属性、类属性
私有属性 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,就变成了一个私有属性,只有内部可以访问,外部不能直接访问或修改. 这样就确保了外部代码不能随意修改对象内部的状态,这样通过 ...
- 【Python】[面性对象编程] 获取对象信息,实例属性和类属性
获取对象信息1.使用isinstance()判断class类型2.dir() 返回一个对象的所有属性和方法3.如果试图获取不存在的对象会抛出异常[AttributeError]4.正确利用对象内置函数 ...
- Python类的实例属性详解
实例属性 1.类被实例化后才会具有的属性 2.一般在_init_()方法中创建并初始化 3.直接使用即定义:self.<属性名> 4.引用方法:self.<属性名> 5.sel ...
- Python类属性,实例属性
1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...
随机推荐
- 7.4 C++标准模板库(STL)的概念
参考:http://www.weixueyuan.net/view/6401.html 总结: 标准模板库为C++提供了完善的数据结构及算法. 标准模板库包括三部分:容器.算法和迭代器. 容器是对象 ...
- Mysql text类型的最大长度
MySQL 3种text类型的最大长度如下: TEXT 65,535 bytes ~64kb MEDIUMTEXT 16,777,215 bytes ~16Mb LONGTEXT 4,294,967, ...
- IOCP IO完成端口
一. IO完成端口概念 IO完成端口的出现是为了解决并发模型中可运行线程上下文切换开销过大而出现的. 在<Windows核心编程>的描述中,IO完成端口是Wnidows系统提供的最复杂的内 ...
- Android开发 ---如何操作资源目录中的资源文件2
Android开发 ---如何操作资源目录中的资源文件2 一.颜色资源管理 效果图: 描述: 1.改变字体的背景颜色 2.改变字体颜色 3.改变按钮颜色 4.图像颜色切换 操作描述: 点击(1)中的颜 ...
- FindResource () RT_HTML 为什么总是出错呢 ?
#include <windows.h> #include <commdlg.h> #include <ole2.h> BOOL GetHtmlResource(L ...
- 循环神经网络-RNN进阶
这部分许多内容要类比CNN来进行理解和解释,所以需要对CNN比较熟悉. RNN的特点 1. 权值共享 CNN权值共享,RNN也有权值共享,在入门篇可以看到RNN结构图中,权重使用的是同样的字母 为什么 ...
- Session和Cookie,以及用户登录验证问题。
参考 :https://blog.csdn.net/u010002184/article/details/79416199 https://www.bbsmax.com/A/RnJW72YJqY/ 首 ...
- java连接操作数据库
Connection 类prepareStatement(String sql) 创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库. PreparedState ...
- 在PHP5.4上使用Google翻译的API报错
/********************************************************************** * 在PHP5.4上使用Google翻译的API报错 * ...
- 【leetcode】58-LengthofLastWord
problem Length of Last Word 只有一个字符的情况: 最后一个word至字符串末尾之间有多个空格的情况: code1 class Solution { public: int ...