Python高级知识点学习(三)

简介:

mro算法

类属性和实例属性的查找顺序

  • 何为类属性:定义在类内部的的一些变量或者方法,都统称为类属性
  • 何为实例属性:定义在对象内部的的一些变量或者方法,都统称为实例属性

对象也就是实例的意思。

class A:
    aa = 1
    def __init__(self, x, y):
        self.x = x
        self.y = y
a = A(2, 3)

类也是对象,看上边代码,实际上有两个空间,A 和 a 两个不同的空间。
单继承时,属性查找方式,向上查找,首先查找对象里,再查找类中

在多继承时,会很复杂

python2.2之前,python里的类叫经典类,经典类继承方式如果不显式继承object,实际上是不会自动继承object,Python3中,经典类已经不存在了,都叫做新式类。
经典类中,深度优先查找 。

Python2.3之后,广度优先也没有了,至今都采用C3算法
Python3多重继承C3算法:

#新式类
class D:
    pass

class E:
    pass

class C(E):
    pass

class B(D):
    pass

class A(B, C):
    pass

print(A.__mro__)

打印结果:
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)
可以看到继承顺序是 A - B - D - C - E - object

类方法静态方法和实例方法

实例方法:实例方法很常见,通常我们在类里定义的都是实例方法,

  • 只是针对于实例进行操作,实例方法中第一个参数:self,self代表的就是实例本身

静待方法:

  • 带@staticmethod装饰器的方法叫静态方法,静态方法不需要接受cls或self,和普通的函数用法一样

类方法:

  • 带@classmethod装饰器的方法叫做类方法,类方法第一个参数是cls,代表的是类本身,(这里的cls可以修改为任意形式的代表)
    def a(self):
        pass
    
    @staticmethod
    def b():
        pass
    
    @classmethod
    def c(cls):
        pass

Python中的私有属性

双下划綫开头表示私有属性,私有属性的访问,只能在类中的公共方法中访问,类外部防问不到,无法通过实例访问。

私有属性不仅仅是变量 还可以是函数。

class User:
    def __init__(self, birthday):
        self.__birthday = birthday

user = User(2000)
print(user.birthday)

运行结果:
AttributeError: 'User' object has no attribute 'birthday'

以上代码块结果就是访问不到私有属性。

但是,私有不是绝对的,只是加了一个小技巧,Python中将私有属性的访问变形成这种:

class User:
    def __init__(self, birthday):
        self.__birthday = birthday
    

user = User(2000)
print(user._User__birthday)

运行结果:
2000

可以看到,通过变量_User__birthday这个就可以访问到私有属性。

Java中的反射机制也是无法做到绝对安全的,从语言层面讲,没有绝对的私有属性,Python简单一些 Java麻烦一些。

Python自省

Python对象自省
何为自省?
自省是通过一定的机制查询到对象的内部结构
使用__dict__魔法函数,dict是用C语言写的 性能高,做了很多优化,推荐使用。

也可以使用dir() ,dir()会列出类中所有属性,推荐使用。

class Student():
    def __init__(self, scool_name):
        self.scool_name = scool_name


if __name__ == "__main__":
    user = Student("zhao")

    #通过__dict__查询属性
    print(user.__dict__)

打印结果:
{'scool_name': 'zhao'}
class Student():
    def __init__(self, name):
        self.name = name


if __name__ == "__main__":
    user = Student("zhao")
    user.__dict__["school_addr"] = "北京市"
    print(user.school_addr)
    print(user.name)
    a = [1, 2]
    print(dir(a))
    print(dir(user))

打印结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'school_addr', 'scool_name']
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

Python中super()函数

super()就是调用父类。

class A:
    def __init__(self):
        print('is A')

class B(A):
    def __init__(self):
        print('is B')
        # 在某些情况下,我们希望在运行完以上代码调用父类的init方法,一般在Python3中使用下面这种方法调用
        super().__init__()

if __name__ == "__main__":
    b = B()

打印结果:
is B
is A

super()就是调用父类,其实这样讲并不准确,super()函数调用其实是按照mro查找的顺序调用的。

class A:
    def __init__(self):
        print("A")


class B(A):
    def __init__(self):
        print("B")
        super().__init__()


class C(A):
    def __init__(self):
        print("C")
        super().__init__()


class D(B, C):
    def __init__(self):
        print("D")
        super().__init__()


if __name__ == "__main__":
    print(D.__mro__)
    d = D()

打印结果:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
D
B
C
A

既然我们重写子类的构造函数, 为什么还要去调用super再次调用父类构造函数?
有些时候,为了使用父类中的一些已经写好的方法,所以会有使用super的情况。

上下文管理器

首先介绍下这种用法:

try:
    print("code started")
    raise KeyError
    return 1
except KeyError as e:
    print ("key error")
    return 2
else:
    print("other error")
    return 3
finally:
    print ("finally")
    return 4

result = exe_try()
print (result)

运行结果:
code started
key error
finally
4

在finally语句块中的代码,不管上边代码是否发生异常都会执行finally中的代码,优先finally中的return,其次return上边的。

上下文管理器,也就是with语句,实质上就是为了解放try finally这种写法而诞生的。

上下文管理器是如何完成的呢?
python是基于协议进行编程的,上下文管理器就是一种协议:上下文管理器协议。

上下文管理器协议可以使用是因为实现了两个魔法函数:
__enter____exit__

class Sample:
    def __enter__(self):
        print("enter")
        # 获取资源
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # 释放资源
        print("exit")

    def do_something(self):
        print("doing something")


with Sample() as sample:
    sample.do_something()

运行结果:
enter
doing something
exit

还有一种方法,可以简便的实现上下文管理器的功能:
@contextlib.contextmanager 可以将一个函数变为上下文管理器

import contextlib

@contextlib.contextmanager
def file_open(file_name):
    print ("file open")
    yield {}
    print ("file end")

with file_open("a.txt") as f_opened:
    print("file processing")

运行结果:
file open
file processing
file end

@contextlib.contextmanager内部会做一些逻辑,其实是利用了生成器的特性。

目录
相关文章
|
2月前
|
Python
python知识点
【8月更文挑战第27天】python知识点
3375 1
WK
|
2月前
|
存储 机器学习/深度学习 JSON
Python入门知识点
Python入门覆盖历史、设计理念、变量、数据类型、控制结构等。了解Python的发展,掌握动态类型的灵活性,熟悉整数、浮点数、字符串等数据类型。学会if/else、for/while循环构建逻辑流程,使用def定义函数,lambda快速创建匿名函数。通过类实现面向对象编程,利用模块和包组织代码。掌握try-except处理异常,open()进行文件操作。利用标准库和第三方库增强功能,理解集合、字典、列表推导式的应用,深入魔法方法、递归、装饰器等高级特性,以及上下文管理器和字符串、列表、元组的操作技巧。
WK
29 0
|
6天前
|
数据采集 数据挖掘 大数据
【Python篇】详细学习 pandas 和 xlrd:从零开始
【Python篇】详细学习 pandas 和 xlrd:从零开始
30 2
|
19天前
|
Python
python之基础知识点
python之基础知识点
24 3
|
4天前
|
设计模式 运维 安全
Python学习—装饰器的力量 (一)
Python学习—装饰器的力量 (一)
12 0
|
4天前
|
Python
Python学习—装饰器的力量 (二)
Python学习—装饰器的力量 (二)
14 0
|
1月前
|
监控 Python Windows
python知识点100篇系列-pysnooper用于调试
PySnooper是一个便捷的Python调试工具,用于监控代码执行过程及局部变量的变化,替代繁琐的打印语句。作为GitHub上的热门开源项目,它通过装饰器自动记录代码执行细节。安装简便,支持多种平台,可通过pip安装。使用时,只需在目标函数上添加装饰器即可实时查看变量变化或将其记录至日志文件。此外,还支持使用with块对特定代码段进行调试。更多详细信息可参阅其官方使用文档。
python知识点100篇系列-pysnooper用于调试
|
2月前
|
存储 Python
Python时间模块四大必备知识点
Python时间模块四大必备知识点
46 4
Python时间模块四大必备知识点
|
2月前
|
Unix 开发者 iOS开发
开发知识点-Python-virtualenv
`virtualenv`通过其简易性、灵活性与高度的可配置性,成为Python开发中推荐的环境隔离工具之一。随着Python生态的发展,类似的工具如 `venv`(Python 3.3+自带的轻量级环境构建工具)和 `pipenv`(提供更复杂的依赖管理功能)也越来越受欢迎,但 `virtualenv`仍保持着重要的地位,尤其是在需要维护旧项目或者系统没有提供最新工具的情况下。
36 1
|
2月前
|
程序员 测试技术 开发工具
豆瓣评分7.9!世界级讲师耗时5年整理出的Python学习手册!
Python是一门流行的开源编程语言,广泛用于各个领域的独立程序与脚本化应用中。它不仅免费、可移植、功能强大,同时相对简单,而且使用起来充满乐趣。从软件业界的任意一角到来的程序员,都会发现Python着眼于开发者的生产效率以及软件质量,因此无论你的项目是大还是小,选择Python都将带来战略性的优势。 今天给小伙伴们分享的这份手册讲述了完整的Python语言,力争满足“语言”和“原理”两个方面的需求,并拥有足够的深度以便实用。废话不多说,下面展示给大家。