zoukankan      html  css  js  c++  java
  • Python基础及语法(九)

    序列化和反序列化

    按照某种规则,把内存的数据保存到文件中,文件是一个字节序列,所以把数据转换成字节序列保存在文件中,这个过程叫序列化,相反,把文件中的字节序列恢复到内存称为反序列化。

     1 import pickle
     2 a = 123
     3 b = '123'
     4 c = [1, 2, 3]
     5 d = {'a': 1, 'b': '2', 3: (3,)}
     6 with open('test', 'wb') as f:  # 序列化
     7     pickle.dump(a, f)
     8     pickle.dump(b, f)
     9     pickle.dump(c, f)
    10     pickle.dump(d, f)
    11 with open('test', 'rb') as f:  # 反序列化
    12     for i in range(4):
    13         x = pickle.load(f)
    14         print(type(x), x)
    15 # <class 'int'> 123
    16 # <class 'str'> 123
    17 # <class 'list'> [1, 2, 3]
    18 # <class 'dict'> {'a': 1, 'b': '2', 3: (3,)}
     1 import pickle
     2 
     3 
     4 class AAA:
     5     tttt = 'ABC'
     6 
     7     def __init__(self):
     8         self.aaaa = 'abcd'
     9 
    10 
    11     def show(self):
    12         print('ABCD')
    13 
    14 
    15 a = AAA()
    16 a.show()  # ABCD
    17 print(a.tttt, a.aaaa)  # ABC abcd
    18 with open('test', 'wb') as f:
    19     pickle.dump(a, f)

    在另一个终端

    1 import pickle
    2 class AAA:
    3     pass
    4 with open('D:/python/test', 'rb') as f:
    5     b = pickle.load(f)
    6 print(b.aaaa)  # abcd

    b.show(),b.tttt均报错,所以只保存了__init__里的内容

     1 import pickle
     2 
     3 
     4 class AAA:
     5     tttt = 'ABC'
     6 
     7     def __init__(self):
     8         self.aaaa = 'abcd'
     9 
    10 
    11     def show(self):
    12         print('ABCD')
    13 
    14 
    15 a = AAA()
    16 a.show()  # ABCD
    17 print(a.tttt, a.aaaa)  # ABC abcd
    18 p = pickle.dumps(a)  # 序列化
    19 with open('text', 'wb') as f:
    20     f.write(p)

    在另一个终端

    1 import pickle
    2 with open('D:/python/test', 'rb') as f:
    3     b = f.read()
    4 c = pickle.loads(b) # 反序列化5 print(c.aaaa) # abcd
    

    这次把类名也保存了下来

    pickle适合Python程序之间使用。跨平台,跨语言,跨写一下pickle不适用,需使用公共协议,如XML、Json、Protocol Buffer等

    Json

    Json(JavaScript Object Notation)是一种轻量级的数据交换格式,支持字符串,必须用双引号包起来,数值(正负整数,浮点数),对象(字典),数组(列表),true(True),false(False),null(None)

    json模块

     1 import json
     2 obj = {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}
     3 f = json.dumps(obj)  # json转码
     4 g = json.loads(f)  # json解码
     5 print(type(obj), obj)  # <class 'dict'> {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}
     6 print(type(f), f)  # <class 'str'> {"name": "Tom", "age": 18, "class": ["Python", "Linux"]}
     7 print(type(g), g)  # <class 'dict'> {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}
     8 with open('test', 'w') as f:
     9     json.dump(obj, f)    # json转码
    10 with open('test', 'r') as f:
    11     h = json.load(f)  # json解码
    12 print(type(h), h)  # <class 'dict'> {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}

    MessagePack

    MessagePack是一个基于二进制的高效的对象序列类库,可用于跨语言通信,它像Json那样但比Json高效

    msgpack模块

     1 import msgpack
     2 obj = {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}
     3 f = msgpack.dumps(obj)  # MessagePack转码
     4 g = msgpack.loads(f)  # MessagePack解码
     5 print(type(obj), obj)  # <class 'dict'> {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}
     6 print(type(f), f)  # <class 'bytes'> b'x83xa4namexa3Tomxa3agex12xa5classx92xa6Pythonxa5Linux'
     7 print(type(g), g)  # <class 'dict'> {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}
     8 with open('test', 'wb') as f:
     9     msgpack.dump(obj, f)    # MessagePack转码
    10 with open('test', 'rb') as f:
    11     h = msgpack.load(f)  # MessagePack解码
    12 print(type(h), h)  # <class 'dict'> {'name': 'Tom', 'age': 18, 'class': ['Python', 'Linux']}

     面向对象

    语言分类

    面向机器(汇编语言):抽象成机器指令,机器容易理解

    面向过程(C语言):按步骤,一步步进行

    面向对象(C++,Java,Python):随着计算机需要解决的问题规模扩大,面向过程不太适合了,而开发出的高级汇编语言,将万事万物抽象为各种对象

    类class

    类是抽象的概念,是万事万物的抽象,是一类事物共同特征的集合

    对象instance,object

    对象是类的具象,是一个实体,对于我们每个人这个个体,都是抽象概念人类的不同的实体

    属性

    对对象状态的抽象,用数据结构来描述

    操作

    对对象状态的抽象,用操作名和实现操作的方法来描述

    面向对象的3要素

    封装:将数据和操作组装在一起,对外只暴露部分接口。

    继承:多复用,不用重复写代码,多继承少修改,使用继承来改变和体现个性

    多态:面向对象编程最灵活的地方,动态绑定

    封装

    定义类就是封装,将类属性和操作组织在里面

     1 class ClassName:  # 命名通常使用大驼峰的命名方式
     2     """a class"""
     3     a = 'abc'  # 定义类属性
     4 
     5     def show(self):  # 定义类方法
     6         return self.__class__.__name__
     7 
     8 
     9 print(ClassName)
    10 print(ClassName.__name__)  # 类名
    11 print(ClassName.__doc__)  # 类文档
    12 print(ClassName.__dict__)  # 类字典
    13 print(ClassName.show)  # 类属性

    类及类属性

    类对象:类也是对象,类定义后生成一个对象

    类属性:类定义中的变量和类的方法都是类的属性,__name__,__doc__等是类的特殊属性

    类变量:属性也是标识符,均为变量

    实例化

     1 class ClassName:
     2     """a class"""
     3     a = 'abc'
     4 
     5     def show(self):
     6         return self.__class__.__name__
     7 
     8 
     9 a = ClassName()  # 实例化
    10 b = ClassName()  # 实例化
    11 print(a.show)
    12 print(b.show)

    __init__方法

    类实例化后要初始化,会调用__init__(self)方法,可以不定义,如果没有定义会隐式调用其父类的

    1 class Test:
    2     def __init__(self):
    3         print('init')
    4 
    5 
    6 print(Test)  # 不调用
    7 Test()  # 调用
    8 a = Test()  # 调用

    初始化可以传入多个参数

     1 class Test:
     2     def __init__(self, a, b):
     3         self.a = a
     4         self.b = b
     5 
     6     def show(self):
     7         print(self.a, self.b)
     8 
     9 
    10 c = Test(123, 'abc')
    11 print(c.a, c.b)  # 123 abc
    12 c.show()  # 123 abc

    注意__init__只能return None

    实例对象instance

    实例化后获得一个该类的实例,就是实例对象

    方法绑定

    实例化后,调用方法,实例对象会绑定到方法上,指向当前调用该方法的实例本身

    slef

     1 class Test:
     2     def __init__(self):
     3         print('init is {}'.format(id(self)))
     4 
     5     def show(self):
     6         print('show is {}'.format(id(self)))
     7 
     8 
     9 a = Test()
    10 print('a is {}'.format(id(a)))
    11 a.show()
    12 # id相等

    类变量和实例变量

     1 class Test:
     2     a = 3  # 类变量
     3 
     4     def show(self):
     5         print(self.a)
     6 
     7 
     8 a = Test()
     9 a.show()  # 3
    10 b = Test()
    11 b.a = 5  # 实例变量
    12 b.show()  # 5

    属性本质

     1 class Test:
     2     a = 3  # 类变量
     3 
     4     def __init__(self, name):
     5         self.name = name
     6 
     7 
     8 print('')
     9 print(Test.__class__, type(Test), Test.__class__ is type(Test))  # <class 'type'> <class 'type'> True
    10 print(Test.__dict__)  # 类字典
    11 b = Test('b')
    12 print('实例')
    13 print(b.__class__, type(b), b.__class__ is type(b))  # <class '__main__.Test'> <class '__main__.Test'> True
    14 print(b.__class__.__name__, type(b).__name__)  # Test Test
    15 print(b.__class__.__dict__)  # 类字典
    16 print(b.__dict__)  # {'name': 'b'}
    17 # 可以看出实例的__class__就是类

    类方法和静态方法

    定义的__init__等方法,这些方法本身都是类的属性,第一个参数必须是self,而self必须指向一个对象,也就是实例化后由实例调用这个方法

    普通函数

     1 class Test:
     2 
     3     def show():
     4         print('普通函数')
     5 
     6 
     7 a = Test
     8 a.show()  # 普通函数
     9 Test.show()  # 普通函数
    10 # 能运行,但不建议这样用

    类方法

    1 class Test:
    2     @classmethod
    3     def show(cls):
    4         print('类方法')
    5 
    6 
    7 a = Test
    8 a.show()  # 类方法
    9 Test.show()  # 类方法

    静态方法

    1 class Test:
    2     @staticmethod
    3     def show():
    4         print('静态方法')
    5 
    6 
    7 a = Test
    8 a.show()  # 静态方法
    9 Test.show()  # 静态方法

    访问控制

     1 class Test:
     2     def __init__(self, a):
     3         self.a = a
     4 
     5     def show(self, i=10):
     6         if 0 < i < 50:
     7             self.a += i
     8 
     9 
    10 b = Test(30)
    11 print(b.a)  # 30
    12 b.show(20)
    13 print(b.a)  # 50
    14 b.show(200)
    15 print(b.a)  # 50

    私有属性

    开头使用两个下划线的属性名就是私有属性,不能被直接访问

     1 class Test:
     2     def __init__(self, a):
     3         self.__a = a
     4 
     5     def show(self, i=10):
     6         if 0 < i < 50:
     7             self.__a += i
     8         return self.__a
     9 
    10 
    11 b = Test(30)
    12 print(b.show(20))  # 50
    13 print(b.show(30))  # 80
    14 print(b.show(50))  # 80
    15 print(b.__dict__)  # {'_Test__a': 80}
    16 print(b._Test__a)  # 80,私有属性通常不直接从外部访问,若要访问可以用这钟方式访问

     保护成员

    开头使用一个下划线的属性名就是保护成员,能被直接访问,通常约定不直接访问

     1 class Test:
     2     def __init__(self, a):
     3         self._a = a
     4 
     5     def show(self, i=10):
     6         if 0 < i < 50:
     7             self._a += i
     8         return self._a
     9 
    10 
    11 b = Test(30)
    12 print(b._a)  # 30
    13 print(b.show(20))  # 50
    14 print(b._a)  # 50

    补丁

    可以使用打补丁的方法修改类

     1 # test1.py
     2 from test2 import Test
     3 from test3 import show
     4 
     5 
     6 print(Test().show())  # test2
     7 Test.show = show  # 打补丁
     8 print(Test().show())  # test3
     9 
    10 # test2.py
    11 class Test:
    12     def show(self):
    13         return 'test2'
    14 
    15 # test3.py
    16 def show(self):
    17     return 'test3'

    属性装饰器

     1 # 使用属性装饰器前
     2 class Test:
     3     def __init__(self, a):
     4         self.__a = a
     5 
     6     def show(self):
     7         return self.__a
     8 
     9     def set(self, i):
    10         self.__a = i
    11 
    12 
    13 b = Test(30)
    14 print(b.show())  # 30
    15 b.set(20)
    16 print(b.show())  # 20
     1 # 使用属性装饰器后
     2 class Test:
     3     def __init__(self, a):
     4         self.__a = a
     5 
     6     @property
     7     def show(self):
     8         return self.__a
     9 
    10     @show.setter
    11     def show(self, i):
    12         self.__a = i
    13 
    14 
    15 b = Test(30)
    16 print(b.show)  # 30
    17 b.show = 20
    18 print(b.show)  # 20

    对象的销毁

    调用__del__方法,编译结束的时候自动调用该方法

     1 # 使用属性装饰器后
     2 class Test:
     3     def __init__(self, a):
     4         self.__a = a
     5 
     6     def show(self):
     7         return self.__a
     8 
     9     def __del__(self):
    10         print('end')
    11 
    12 
    13 a = Test('HI')
    14 print(a.show())  # HI
    15 # end

    方法重载

    Python没有重载,Python语法本身实现了重载

    类的继承

    基本概念

    类的三要素:封装,继承,多态

     1 # 没有继承
     2 class TestOne:
     3     def show(self):
     4         print('{} show'.format(self.__class__.__name__))
     5 
     6 
     7 class TestTwo:
     8     def show(self):
     9         print('{} show'.format(self.__class__.__name__))
    10 
    11 
    12 test1 = TestOne()
    13 test1.show()  # TestOne show
    14 test2 = TestTwo()
    15 test2.show()  # TestTwo show
     1 # 有继承
     2 class TestOne:
     3     """1"""
     4     def show(self):
     5         print('{} show'.format(self.__class__.__name__))
     6 
     7 
     8 class TestTwo:
     9     """2"""
    10     def dict(self):
    11         print(self.__class__.__dict__)
    12 
    13 
    14 class TestThree(TestOne, TestTwo):
    15     """3"""
    16     pass
    17 
    18 
    19 test1 = TestOne()
    20 test1.show()  # TestOne show
    21 test2 = TestTwo()
    22 test2.dict()  # TestTwo的字典
    23 test3 = TestThree()
    24 test3.show()  # TestThree show
    25 test3.dict()  # TestThree的字典
    26 print(TestThree.__mro__)  # 显示方法查找顺序,基类的元组
    27 print(TestThree.mro())  # 同上
    28 print(TestThree.__base__)  # 返回基类元组的第一项
    29 print(TestThree.__bases__)  # 返回基类元组

    方法的覆盖重写

     1 class TestOne:
     2     """1"""
     3     def show(self):
     4         print('{} show'.format(self.__class__.__name__))
     5 
     6 
     7 class TestTwo(TestOne):
     8     """2"""
     9     def show(self):
    10         print('覆盖了')
    11 
    12 
    13 test1 = TestOne()
    14 test1.show()  # TestOne show
    15 test2 = TestTwo()
    16 test2.show()  # 覆盖了

    单继承

    定义类的时候继承项只有一个基类的是为单继承

    多继承

    一个类继承自多个类就是多继承

    多继承的弊端:多个父类有相同的方法名的时候不清楚继承哪个

    解决方法:Python使用C3算法解决,在类被创建出来的时候就建立了MRO列表

    其它解决方法:装饰器,Mixin

    多态

    在面向对象中,父类,子类,联系在一起,如果通过一套方法,就可以实现不同表现,就是多态

  • 相关阅读:
    python assert断言函数
    Python中错误之 TypeError: object() takes no parameters、TypeError: this constructor takes no arguments
    python 3.5构建WINDOWS推送服务
    Python调用(运行)外部程序
    sqlalchemy相关知识
    利用rabbit_mq队列消息实现对一组主机进行命令下发
    Centos 下安装Zabbix Linux 客户端
    Lynis 2.2.0 :面向Linux系统的安全审查和扫描工具
    防暴力破解 Fail2Ban之python
    linux服务器被攻击处理过程
  • 原文地址:https://www.cnblogs.com/bgr1115/p/12882460.html
Copyright © 2011-2022 走看看