前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python day7 面向对象高级编程 (2)

Python day7 面向对象高级编程 (2)

原创
作者头像
昆兰
发布2024-08-01 21:02:02
1290
发布2024-08-01 21:02:02
举报
文章被收录于专栏:廖雪峰python学习笔记

数据封装、继承和多态只是面向对象程序设计中最基础的3个概

使用slots和@property

slots限制实例的绑定属性

想要限制实例的属性,例如只允许对Student实例添加name和age属性:Python允许在定义class的时候,定义一个特殊的slots变量,来限制该class实例能添加的属性

代码语言:python
代码运行次数:0
复制
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'

就会发现类的实例属性score属性不能绑定了,slots定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

@property

能检查参数,又可以用类似属性这样简单的方式来访问类的变量

代码语言:python
代码运行次数:0
复制
class Student(object):
    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2015 - self._birth

上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来

代码语言:python
代码运行次数:0
复制
#要特别注意:属性的方法名不要和实例变量重名
#错误案例
class Student(object):
    # 方法名称和实例变量均为birth:
    @property
    def birth(self):
        return self.birth

多重继承

代码语言:python
代码运行次数:0
复制
class Dog(Mammal, Runnable): #同时获得多个父类的所有功能
    pass

这样额外的功能加入设计也称为MixIn,如Python自带了TCPServer和UDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixIn和ThreadingMixIn提供。

`

定制类

返回字符

这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据

代码语言:python
代码运行次数:0
复制
class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self): 
        return 'Student object (name=%s)' % self.name
    __repr__ = __str__

 #__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串

迭代返回

代码语言:python
代码运行次数:0
复制
class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化两个计数器a,b

    def __iter__(self):
        return self # 实例本身就是迭代对象,故返回自己

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b # 计算下一个值
        if self.a > 100000: # 退出循环的条件
            raise StopIteration()
        return self.a # 返回下一个值


>>> for n in Fib():
...     print(n)
...
1
1
2
3
5
...
46368
75025

元素处理

getitem/setitem()/delitem()

像list那样按照下标取出元素,需要实现getitem()方法

代码语言:python
代码运行次数:0
复制
class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a

属性获取

要避免这个错误,除了可以加上一个score属性外,Python还有另一个机制,那就是写一个getattr()方法,动态返回一个属性

只有在没有找到属性的情况下,才调用getattr,已有的属性,比如name,不会在getattr中查找

完全动态调用的特性非常灵活

调用实例方法

调用实例方法时,我们用instance.method()来调用,也可以直接对实例进行调用

callable()函数,我们就可以判断一个对象是否是“可调用”对象

枚举类

Enum可以使得每个常量都是class的一个唯一实例

代码语言:python
代码运行次数:0
复制
# 1
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)
  • Enum的第一个参数是枚举的类名,第二个参数是一个包含枚举成员名称的元组
  • 遍历Month枚举类中的所有成员。枚举成员和它们的名称都存储在特殊的members属性中,这是一个字典;Month.members.items()会返回一个包含(成员名称, 成员)对的迭代器
  • 这行代码在循环中打印每个成员的名称和值,member.value是自动分配给枚举成员的一个唯一值,默认从1开始递增

输出结果为:

Jan => Month.Jan , 1 Feb => Month.Feb , 2

Mar => Month.Mar , 3 Apr => Month.Apr , 4

May => Month.May , 5 Jun => Month.Jun , 6

Jul => Month.Jul , 7 Aug => Month.Aug , 8

Sep => Month.Sep , 9 Oct => Month.Oct , 10

Nov => Month.Nov , 11 Dec => Month.Dec , 12

也可以写成

代码语言:python
代码运行次数:0
复制
from enum import Enum, unique
@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

元类(后面再来补充)

type()动态创建类

type()函数可以查看一个类型或变量的类型,Hello是一个class,它的类型就是type,而h是一个实例,它的类型就是class Hello

metaclass控制类的创建行为

代码语言:python
代码运行次数:0
复制
# metaclass是类的模板,所以必须从`type`类型派生:
class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)

ORM

基类

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用slots和@property
    • slots限制实例的绑定属性
      • @property
      • 多重继承
      • 定制类
        • 返回字符
          • 迭代返回
            • 元素处理
              • 属性获取
                • 调用实例方法
                • 枚举类
                • 元类(后面再来补充)
                  • type()动态创建类
                    • metaclass控制类的创建行为
                      • ORM
                        • 基类
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档