IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python学习杂记4:类的高级特性 -> 正文阅读

[Python知识库]Python学习杂记4:类的高级特性

类的高级特性


访问控制

  • 变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

  • 以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

  • 如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量,但不建议这样做。

继承和多态

class Animal(object):
    def run(self):
        print('Animal is running...')
        
class Dog(Animal):# 继承:Dog子类获得了父类Animal的全部功能,Dog既是Dog类也是Animal类
    # 多态:当子类和父类都存在相同的run()方法时,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。
    def run(self):
        print('Dog is running...')

class Cat(Animal):# Cat子类获得了父类Animal的全部功能,Cat既是Cat类也是Animal类
    def run(self):
        print('Cat is running...')
               
def run_twice(animal):
    animal.run()
    animal.run()

新增一个Animal的子类,不必对run_twice()做任何修改,只要确保run()方法编写正确,不用管原来的代码是如何调用的,原因就在于多态。甚至不必须传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。

对扩展开放:允许新增Animal子类;

对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

获取对象信息

  • type()返回对应的Class类型。
>>> type(123)
<class 'int'>
  • instance()判断是否是某一类型
>>> isinstance(123, int)
True
  • dir()获得一个对象的所有属性和方法
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
  • hasattr()返回是否有某一属性
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
  • setattr()设置一个属性
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
  • getattr()获取属性
>>> getattr(obj, 'y') # 获取属性'y'
19

实例属性和类属性

实例属性属于各个实例所有,互不干扰,通过self或实例变量访问。

类属性属于类所有,所有实例共享一个属性,通过类名访问。

不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。

class Student(object):
    count = 0 # 类属性
    def __init__(self, name):
        self.name = name # 实例属性
        Student.count+=1

高级特性

__slots__

定义一个特殊的__slots__变量,来限制该class实例能添加的属性,只有放入__slots__的属性可以被动态绑定。

class Student(object):
    __slots__ = ('name', 'age')
    
>>> 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'

__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

@property

@property装饰器负责把一个方法变成属性调用

class Student(object):

    @property # 把birth方法变成属性调用***.birth
    def birth(self):
        return self._birth

    @birth.setter # 把birth方法变成属性调用***.birth=...
    def birth(self, value):
        self._birth = value

    @property #只定义getter方法,不定义setter方法就是一个只读属性
    def age(self):
        return 2021 - self._birth
    
>>> s=Student()
>>> s.birth=2001
>>> s.age
20

上面的birth是可读写属性,而age就是一个只读属性

多重继承

通过多重继承,一个子类可以同时获得多个父类的所有功能。

class Dog(Mammal, Runnable):
    pass

MixIn的目的就是给一个类增加多个功能。在设计类的时候,优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系。

class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
    pass

枚举类

from enum import Enum,unique

@unique	# @unique装饰器可以帮助我们检查保证没有重复值。
class Gender(Enum):
    Male = 0
    Female = 1

    

类的常见特殊方法

  • __str__()

用print打印一个实例时,调用__str__(),返回一个字符串

>>> print(Student('A'))
Student object (name: A)
  • __repr__(),直接显示变量调用,为调试服务
>>> s
Student object (name: A)
  • __iter__()方法,该方法返回一个迭代对象,例如在for循环开始时调用

  • __getitem__(self,n)按照下标取出元素

  • __getattr__()方法,动态返回一个属性。当调用不存在的属性时调用该方法。

    class Chain(object):
    
        def __init__(self, path=''):
            self._path = path
    
        def __getattr__(self, path):
            return Chain('%s/%s' % (self._path, path)) # 返回一个对象,该对象的_path=self._path+path
    
        def __str__(self):
            return self._path
    
        __repr__ = __str__ #使得__repr__方法等同于__str__
        
    >>> Chain().status.user.timeline.list 
    # 链式调用,首先Chain()调用__init__创建Chain对象,_path为空。遇到不存在的status属性,调用__getattr__,返回一个_path=''+'status'的Chain对象,以此类推……,最终创建_path='/status/user/timeline/list'的对象,调用__repr__输出。
    '/status/user/timeline/list'
    
  • __call__()直接对实例进行调用

    #用法实例
    >>> s() # 不需要传入参数
    My name is Michael.
    
    #############################################################################################
    class Chain(object):
        def __init__(self, path=''):
            self.__path = path
    
        def __getattr__(self, path):
            return Chain('%s/%s' % (self.__path, path))
    
    
        def __call__(self, path):
            return Chain('%s/%s' % (self.__path, path))
    
    
        def __str__(self):
            return self.__path
    
        __repr__ = __str__
        
    # 链式调用
    >>> Chain().users('michael').repos
    # 首先Chain()调用__init__创建Chain对象,_path为空。遇到不存在的users属性,调用__getattr__,返回一个_path=''+'/users'的Chain对象。然后遇到('michael')。调用__call__,返回一个_path+='/michael'的Chain对象……
    /users/michael/repos
    
  • instance.method()调用实例方法

  • callable()判断对象是否是可调用对象

对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 23:06:26  更:2021-08-10 23:07:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/30 12:54:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码