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

Python干货——_ _slots__属性

原创
作者头像
Java学术趴
发布2022-06-18 21:26:05
4220
发布2022-06-18 21:26:05
举报
文章被收录于专栏:Java全栈·Java全栈·

👨‍🎓作者:Java学术趴 🏦仓库:GithubGitee ✏️博客:CSDN掘金InfoQ云+社区 🚫特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。 🙏版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。

☠️每日毒鸡汤:这个社会是存在不公平的,不要抱怨,因为没有用!人总是在反省中进步的!

👋大家好!我是你们的老朋友Java学术趴

第二十章 动态添加属性和方法

20.1 概念

  • 动态语言:运行时可以改变其结构的语言,例如新的函数、对象、甚至代码可以被引入,已有的函数可以被删除或是其他结构上的变化。如php、js、python都是动态语言,C、C#、Java都是静态语言。所以python可以在程序运行过程中添加属性和方法。

20.2 动态添加属性

给类的实例对象添加额外属性

代码语言:javascript
复制
# 动态添加属性和方法
class Student(object):
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.age)
​
    pass
​
​
# 创建一个类实例对象
student = Student('小明', 30)
# 使用类实例对象原有的属性
print(student.name)
​
# 动态添加实例对象属性。此时并不是给类添加了这个room属性
# 此时只是给这个对象添加了额外的room属性,其他的实例对象不会有这个room属性
student.room = 'python二班'
print(student.room)
# python二班
​
​
student2 = Student('小王', 40)
# student2没有room属性,student只是给自己添加了额外的room属性
# print(student2.room) 报错
复制代码

给类添加额外属性

代码语言:javascript
复制
# 动态添加属性和方法
class Student(object):
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.age)
​
    pass
​
​
# 给类添加属性。通过类进行点
Student.height = '175'
​
​
# 实例对象可以访问类属性。
# 实例对象可以访问类属性以及实例属性
# 类只能访问类属性,不可以访问实例属性
student = Student('张三', 30)
print(student.height)
# 175
复制代码

20.3 动态添加方法

动态添加实例方法:需要使用types

代码语言:javascript
复制
# 动态添加属性和方法
​
# 导入添加方法的库
import types
​
# 定义动态添加的实例对象方法
# 定义的实例对象的方法必须存在 self 这个参数,否则在绑定的时候会报错
# 即使方法体中用不到这个 self 参数,这里也不可以省略
def show(self):
    print('{}的身高是:{}kg,班级是:{}'.format(self.name, self.height, Student.room))
    print(1)
    pass
​
​
class Student(object):
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.age)
​
    pass
​
​
student = Student('小明', 20)
# 动态添加实例对象属性
student.height = '175'
# 动态添加类属性
Student.room = 'python一班'
​
# 给实例对象动态添加方法。
# 首先需要通过types.MethodType绑定方法,第一个参数是绑定的方法名,第二个是实例对象名
student.showInfo = types.MethodType(show, student)
​
# 调用动态绑定的实例方法
student.showInfo()
# 小明的身高是:175kg,班级是:python一班
# 1
​
student1 = Student('小王', 30)
# 此时给实例对象添加额外的方法,只是给student进行了添加,student1需要再次进行绑定
# student1.showInfo() 报错
复制代码

动态添加类方法和静态方法:类名.方法名 = xxx 形式绑定类方法

代码语言:javascript
复制
# 动态添加属性和方法
​
# 导入添加方法的库
import types
​
# 定义一个类方法
# 这个类方法必须存在 cls 这个参数,不论方法体有没有用到,都必须给定这个参数
# 否则在绑定方法的时候会报错
@classmethod
def eat(cls):
    print('吃饭')
    pass
​
​
# 定义一个静态方法
# 静态方法,这个 cls 参数可有可无
@staticmethod
def drink():
    print('喝水')
    pass
​
class Student(object):
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.age)
​
    pass
​
​
student = Student('小明', 30)
​
# 给Student类绑定类方法eat()
Student.eat = eat
# 调用额外添加的类方法
# 这里的参数不能传递,如果给了会报错
Student.eat()
# 吃饭
​
# 给Student类绑定额外的静态方法
Student.drink = drink
Student.drink()
# 喝水
​
# 实例对象可以访问到额外添加的类方法和类静态方法
student.eat()
student.drink()
复制代码

第二十一章 _ _slots__属性

21.1 概念

  • python是动态语言,在运行的时候可以动态添加属性。如果是限制在运行时候给类添加属性,Python允许在定义class的时候,定义一个特殊的_ _slots__变量,来限制该class实例能添加的属性。
  • 只有在_ _slots__变量中的属性才能添加,没有在slots变量中的属性添加失败。可以防止其他人在调用类的时候胡乱添加啊属性或方法。只有子类声明 slots 的时候,才会继承父类的slots。如果子类不声明slots变量则不会进行继承

使用方式

代码语言:javascript
复制
# 通过 __slots__  控制添加的额外实例属性还有类属性
class Student(object):
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.age)
​
    # 如果不把name以及age属性添加到这个 __slots__,那么此时name和age为只读属性,不可以从新赋值
    # 在创建对象的时候就无法给name和age赋值,所以这里必须把这两个参数写上
    __slots__ = ('sex', 'room', 'name', 'age')
    pass
​
​
student = Student('小明', 20)
​
print(student.name)
print(student.age)
​
# 添加额外的实例属性并且是__slots__中存在的
student.sex = '男'
print(student.sex)
# 男
​
# 添加额外的实例属性,是__slots__中不存在的
# student.height = '186' 报错
​
# 给类添加额外的属性并且是 __slots__ 中存在的
Student.sex = '男'
print(Student.sex)
# 男
​
# 添加额外的实例属性,是__slots__中不存在的
# student.height = '186' 报错
​
​
# 如果不存在 __slots__ ,那么所有的实例属性都会存储在一个字典中。字典是非常占用内存空间的
# 当存在 __slots__ 的时候,所有的实例属性就不会存储到这个字典中,而是把属性存储到 __slots__ 变量中
print(student.__dict__)
# {'name': '小明', 'age': 20, 'sex': '男'}
复制代码

slots变量在父子类之间的继承

子类必须声明 slots 变量才会继承父类的,否则不会继承

代码语言:javascript
复制
# 通过 __slots__  控制添加的额外实例属性还有类属性
class People(object):
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.age)
​
    # 如果不把name以及age属性添加到这个 __slots__,那么此时name和age为只读属性,不可以从新赋值
    # 在创建对象的时候就无法给name和age赋值,所以这里必须把这两个参数写上
    __slots__ = ('sex', 'room', 'name', 'age')
    pass
​
​
class Student(People):
    pass
​
​
student = Student('小李', 18)
# 当子类没有声明 slots 变量的时候不会继承父类的 slots 变量
# 此时可以给子类随意动态添加属性值
student.height = '165'
print(student.height)
# 165
​
class Teacher(People):
    # 子类声明 slots 变量,此时会继承父类的并且可以添加额外的属性
    # 子类尽量不要去重写父类已经存在的属性。重复声明会占用内存空间
    __slots__ = 'weight'
    pass
​
teacher = Teacher('王老师', 40)
​
# 继承父类中 slots变量 中的属性
print('教师的姓名:{},教师的年龄:{}'.format(teacher.name, teacher.age))
# 教师的姓名:王老师,教师的年龄:40
​
# 此时子类继承了父类的 slots 变量,就不可以随意的添加属性了
# teacher.height = '175' 报错,因为slots中不存在height属性
​
# 可以添加 slots 中存在的属性值
teacher.weight = '50'
print(teacher.weight)
# 50

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第二十章 动态添加属性和方法
    • 20.1 概念
      • 20.2 动态添加属性
        • 20.3 动态添加方法
        • 第二十一章 _ _slots__属性
          • 21.1 概念
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档