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 > ...
随机推荐
- 8.2 C++标准输出流对象
参考:http://www.weixueyuan.net/view/6408.html 总结: iostream头文件,包含了该头文件后,我们就可以直接使用这些对象,包含标准的输出流对象cout.ce ...
- ajax返回数据定义为全局变量
var result; //定义全局变量 $(document).ready(function(){ $.ajax({ type:'PO ...
- 驱动链表(LIST_ENTRY)
DDK提供了两种链表的数据结构,双向链表和单向链表,其定义如下: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIS ...
- ubuntu 实用命令收集
dig 查看域名解析 最下面server为DNS解析地址 dig google.com sudo -s 转为root方式 curl ip.gs 获取本机外网的ip地理地址 开启ipv4转发功能 /et ...
- <HBase><Scan>
Overview The Scan operation for HBase. Scan API All operations are identical to Get with the excepti ...
- day 36 关于io模型的问题 阻塞 和多路复用
# from gevent import spawn,monkey;monkey.patch_all()# from socket import *# def server(ip,port):# se ...
- 【转】CEF3加载网页---多字节字符集和UNICODE字符集
static char* MBSCToCEF(const char* mbcsStr) { wchar_t* wideStr; char* utf8Str; int charLen; charLen ...
- css 利用border 绘制三角形. triangle
1.基础三角形. <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- python django 创建虚拟环境
DRF---django-rest-framework: 1.通过一个案例简单回顾一下django, 一.前后端分离,不分离 不分离:前端页面的显示,都是由后端返回的,就是说后端处理了参数,数据库,之 ...
- python flask实现小项目方法
本文目的是为了完成一个项目用到的flask基本知识,例子会逐渐加深.最好对着源码,一步一步走. 下载源码,运行 pip install -r requirements.txt 建立环境 python ...