当前位置:   article > 正文

Python个人学习笔记_attributeerror: 'dict' object has no attribute 'va

attributeerror: 'dict' object has no attribute 'value
  • 一、Python基础##

1. 数据类型

常用的有:
整数、浮点数、字符串,
dict: 字典类型,key-vaule 形式
set:集合型 元素不重复,只能存key
list: 列表 有序集合

2. 字符串和编码

ASCII编码:1个字节
Unicode:2个字节
UTF-8:可变长编码

3. 循环

for…in 循环

names=['aaa','bbb','ccc']
for name in names
	print(name)
  • 1
  • 2
  • 3
  • 二、函数

1. 函数定义

使用 def 关键字

  • 三、高级特性#

1. 切片

>>>L = ['aaa', 'bbb', 'ccc', 'ddd', 'eee']

>>> [L[0], L[1], L[2]]
['aaa', 'Sarah', 'Tracy']

>>> L[0:3]
['aaa', 'bbb', 'ccc']

>>> L[1:3]
['bbb', 'ccc']

>>> L[:]
['aaa', 'bbb', 'ccc', 'ddd', 'eee']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2. 迭代
使用for…in操作/遍历一个list等集合
是一种比较抽象的遍历方式


>>> for ch in 'ABC':
...     print(ch)
...
A
B
C
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 列表生成式

使用 for…in 结构创建列表

>>>[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

>>>[x * x for x in range(1, 11) if x%2==0]  #当x为偶数时
[4, 16, 36, 64, 100]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4. 生成器
generator生成器, 可压缩存储空间

>>> L = [x * x for x in range(10)]#一个完整列表
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]


>>> g = (x * x for x in range(10))#创建了一个generator,压缩数据
>>> g
<generator object <genexpr> at 0x1022ef630>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5. 迭代器
可以直接作用于for循环的对象统称为可迭代对象:Iterable
可使用isinstance()判断一个对象是否是Iterable对象

>>> from collections.abc import Iterable
>>> isinstance('abcdefg', Iterable)
True
>>> isinstance(100, Iterable)
False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 四、函数式编程#

1. 高阶函数

map/reduce

map : map()函数接收两个参数,一个是函数,一个是迭代序列

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))  #str()为字符串转换函数
['1', '2', '3', '4', '5', '6', '7', '8', '9']
  • 1
  • 2

reduce:

#reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)


>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

filter

filter()接收一个函数和一个序列,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素

def is_odd(n):
    return n % 2 == 1  #奇数返回True
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
结果: [1, 5, 9, 15]  删掉偶数,留下奇数
  • 1
  • 2
  • 3
  • 4

sorted: 排序函数

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
    return t[0]
L2 = sorted(L, key=by_name)
print(L2)
#结果 [('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2. 返回函数

函数作为返回值
如下,lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum   #返回sum()函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 匿名函数

匿名函数,没有函数名称,举例: lambda x: x * x实际上就是

def f(x):
    return x * x
  • 1
  • 2

也可把匿名函数作为值返回

def build(x, y):
    return lambda: x * x + y * y
  • 1
  • 2

4. 装饰器
函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。

def now():
	print('2020-6-21')


>>> f = now
>>> f()
2020-6-21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

函数对象有一个__name__属性,可以拿到函数的名字:

def now():
	print('2020-6-21')
>>>now.__name__
'now
  • 1
  • 2
  • 3
  • 4

装饰器的作用就是可以定义之后,给每个函数都装饰
显示程序执行的开始、结束,显示函数执行时间

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log          # 相当于执行now = log(now)
def now():
    print('2015-3-25')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 五、面向对象编程#

1. 类和实例

类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”

class Student(object):
    pass
bart = Student()
bart.name = 'Bart Simpson'
print(bart.name)
#结果  'Bart Simpson'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

__init__方法,用于初始化,类似于JAVA中的构造函数

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
bart = Student('Bart Simpson', 59)
print(bart.name,bart.score)
#结果 'Bart Simpson' 59
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

数据封装,在上面的Student类中,每个实例就拥有各自的name和score这些数据。我们可以通过函数来访问这些数据,比如打印一个学生的成绩,
封装,即实例变量上调用,不需要知道内部实现细节

def print_score(std):
	print('%s: %s' % (std.name, std.score))
print_score(bart)
#结果 Bart Simpson: 59
  • 1
  • 2
  • 3
  • 4

2. 访问限制

让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

class Student(object):
    def __init__(self, name, score):
        self.__name = name
        self.__score = score
    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))
bart = Student('Bart Simpson', 59)
print(bart.__name)
#结果报错 AttributeError: 'Student' object has no attribute '__name'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

若要访问私有变量,可在类中增加get方法,get_nameget_score
若要修改私有变量,可增加set方法,set_nameset_score

class Student(object):
    ...
get方法
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score
#set 方法
	def set_score(self, score):
        self.__score = score
	def set_score(self, name):
        self.__name = name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3. 继承和多态

继承

定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
动物类

class Animal(object):
    def run(self):
        print('Animal is running...')
  • 1
  • 2
  • 3

编写Dog和Cat类时,就可以直接从Animal类继承:

class Dog(Animal):
    pass
class Cat(Animal):
    pass
  • 1
  • 2
  • 3
  • 4

此时Dog和Cat类都有一个run()方法

dog = Dog()
dog.run()
cat = Cat()
cat.run()
#结果 
Animal is running... 
Animal is running...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

多态

子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run(),
在继承父类的基础上,添加自己的属性/特点

class Animal(object):
    def run(self):
        print('Animal is running...')
def run_twice(animal):
    animal.run()
class Dog(Animal):
    def run(self):
        print('Dog is running...')
class Cat(Animal):
    def run(self):
        print('Cat is running...')
print(run_twice(Animal()))
print(run_twice(Dog()))
print(run_twice(Cat()))
#结果
Animal is running...
Dog is running...
Cat is running...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4. 获取对象信息
基本类型都可以用type()判断:

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用isinstance()
class的继承关系来说,使用type()不方便,如果继承关系是:object -> Animal -> Dog -> Husky

a = Animal()
d = Dog()
h = Husky()
print(isinstance(d, Dog) and isinstance(d, Animal))
#结果 True
  • 1
  • 2
  • 3
  • 4
  • 5

使用dir()函数,获得一个对象的所有属性和方法

print(dir('ABC'))
#结果 ['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
  • 1
  • 2

配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:

class MyObject(object):
	def __init__(self):
		self.x = 9
	def power(self):
		return self.x * self.x
obj = MyObject()
hasattr(obj, 'x')# 有属性'x'吗?
#结果 True
hasattr(obj, 'y')# 有属性'y'吗?
#结果 False
setattr(obj, 'y', 19) #设置一个属性'y'
hasattr(obj, 'y') # 有属性'y'吗?
#结果 True
getattr(obj, 'y') # 获取属性'y'
#结果 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5. 实例和类属性

Python是动态语言,根据类创建的实例可以任意绑定属性。
给实例绑定属性的方法是通过实例变量,或者通过self变量

class Student(object):
    def __init__(self, name):
        self.name = name
s = Student('Bob')
s.score = 90
  • 1
  • 2
  • 3
  • 4
  • 5

相同名称的实例属性将屏蔽掉类属性,但是当删除实例属性后,再使用相同的名称,访问到的将是类属性。

  • 六、面向对象高级编程#

1. 使用__slots__

要限制实例的属性,例如:只允许对Student实例添加name和age属性,
在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
使用__slots__要注意:__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

class Student(object):
    __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
  • 1
  • 2

2. 使用@property

Python内置的@property装饰器可以把一个方法变成属性调用

class Student(object):
    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

#测试
>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3. 多重继承

#动物类
class Animal(object):
    pass


# 大类:
class Mammal(Animal):
    pass

class Bird(Animal):
    pass


# 各种动物:
class Dog(Mammal):
    pass

class Bat(Mammal):
    pass

class Parrot(Bird):
    pass

class Ostrich(Bird):
    pass
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

给动物再加上Runnable和Flyable的功能,只需要先定义好Runnable和Flyable的类

class Runnable(object):
    def run(self):
        print('Running...')

class Flyable(object):
    def fly(self):
        print('Flying...')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

需要Runnable功能的动物,就多继承一个Runnable,例如Dog

class Dog(Mammal, Runnable):
    pass
  • 1
  • 2

需要Flyable功能的动物,就多继承一个Flyable,例如Bat

class Bat(Mammal, Flyable):
    pass
  • 1
  • 2

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

4. 定制类

__str__

** 定义一个Student类,打印一个实例**

class Student(object):
	def __init__(self, name):
		self.name = name
print(Student('Michael'))
#结果 <__main__.Student object at 0x109afb190>
  • 1
  • 2
  • 3
  • 4
  • 5

定义__str__方法

class Student(object):
	def __init__(self, name):
		self.name = name
	def __str__(self):
		return 'Student object (name: %s)' % self.name
print(Student('Michael'))
#结果 Student object (name: Michael)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

__iter__

如果一个类想被用于for ... in循环,类似listtuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

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() #StopIteration错误, for...in 退出循环
        return self.a # 返回下一个值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

__getitem__
要像list那样按照下标取出元素,需要实现__getitem__()方法
使用if语句实现切片,__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:

class Fib(object):
    def __getitem__(self, n):
	if isinstance(n, int): # n是索引
		a, b = 1, 1
		for x in range(n):
			a, b = b, a + b
        return a
	if isinstance(n, slice): # n是切片
		start = n.start
        stop = n.stop
        if start is None:
			start = 0
            a, b = 1, 1
            L = []
		for x in range(stop):
			if x >= start:
				L.append(a)
				a, b = b, a + b
		return L
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

__call__
定义一个__call__()方法,就可以直接对实例进行调用

class Student(object):
    def __init__(self, name):
        self.name = name
    def __call__(self):
        print('My name is %s.' % self.name)
#测试
>>> s = Student('Michael')
>>> s()
My name is Michael.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

通过callable()函数,可以判断一个对象是否是“可调用”对象。

5. 枚举类

from enum import Enum导入枚举类所需的包
枚举类型定义一个class类型,然后,每个常量都是class的一个唯一实例

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)
#结果
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 七、错误、调试和测试#

1. 错误处理

错误处理机制
try...except...finally...

try:
    print('try...')
    r = 10 / 0
    print('result:', r)
except ZeroDivisionError as e:  #捕获异常,类似于java中的catch
    print('except:', e)
finally:
    print('finally...')
print('END')
#测试
try...
except: division by zero
finally...
END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2. 调试

1.使用print

直接打印有问题的地方

2.断言,使用assert

def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n
def main():
    foo('0')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

表达式n != 0应该是True,否则,根据程序运行的逻辑,将断言失败,assert语句抛出AssertionError
3.使用logging

import logging
logging.basicConfig(level=logging.INFO)#设置基本为INFO,其他将不输出
s = '0'
n = int(s)
logging.info('n = %d' % n)  
logging.debug('n = %d' % n)#将不输出
print(10 / n)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4.单步调试(可配合IDE)

3. 单元测试

引入Python自带测试模块,import unittest
编写测试类,继承unittest.TestCase,如下,以test开头的方法就是测试方法,不以test开头的方法不被认为是测试方法,测试的时候不会被执行
每一类测试都需要编写一个test_xxx()方法

lass Dict(dict):
    def __init__(self, **kw):
        super().__init__(**kw)
    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
    def __setattr__(self, key, value):
        self[key] = value
class TestDict(unittest.TestCase):
    def test_init(self):
        d = Dict(a=1, b='test')
        self.assertEqual(d.a, 1)
        self.assertEqual(d.b, 'test')
        self.assertTrue(isinstance(d, dict))
    def test_key(self):
        d = Dict()
        d['key'] = 'value'
        self.assertEqual(d.key, 'value')
    def test_attr(self):
        d = Dict()
        d.key = 'value'
        self.assertTrue('key' in d)
        self.assertEqual(d['key'], 'value')
    def test_keyerror(self):
        d = Dict()
        with self.assertRaises(KeyError):
            value = d['empty']
    def test_attrerror(self):
        d = Dict()
        with self.assertRaises(AttributeError):
            value = d.empty
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

使用断言,assertEqual()self.assertEqual(abs(-1), 1) abs()返回结果与预期1相等,则正常
若不相等self.assertEqual(abs(-1), 0),则抛出异常

可通过以下语句运行

if __name__ == '__main__':
    unittest.main()
  • 1
  • 2

4. 文档测试

使用doctest
doctest严格按照Python交互式命令行的输入和输出来判断测试结果是否正确

  • 八、IO编程#

1. 文件读写

读文件
使用Python内置的open()函数,传入文件名和标示符,以读文件的模式打开一个文件对象
如果文件不存在,open()函数就会抛出一个IOError的错误

f=open(filename, 'r')  #读文本
f = open(filename, 'rb') #读二进制
  • 1
  • 2

最后一步调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的
一般使用try...finally实现正确的关闭文件
要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件:

f = open(filename, 'r', encoding='gbk', errors='ignore')
  • 1

写文件

调用open()函数时,传入标识符’w’或者’wb’表示写文本文件或写二进制文件

f = open(filename, 'w')#文本
f = open(filename, 'wb')#二进制,读取二进制文件,比如图片、视频等等,用'rb'模式打开文件
  • 1
  • 2

同样最后一步调用close()方法关闭文件

用with语句可以自动调用.close()方法,保证正常关闭文件

with open(filename, 'w') as fw:  #写
    fw.write('Hello, world!')
with open(filename, 'r') as fr:  #读
    print(fr.read())
  • 1
  • 2
  • 3
  • 4

2. StringIO和BytesIO

StringIO,

在内存中读写str,先引入from io import StringIO
str写入StringIO

from io import StringIO
f = StringIO()
f.write('hello')  #返回 5
f.write(' ')      #返回 1
f.write('world!') #返回 6
f.getvalue()     #返回 hello world!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

BytesIO

在内存中读写bytes,引入from io import BytesIO

f = BytesIO()
f.write('中文'.encode('utf-8')) #返回 6
print(f.getvalue()) #返回 b'\xe4\xb8\xad\xe6\x96\x87'
  • 1
  • 2
  • 3

3. 操作文件和目录

Python内置的os模块可直接调用操作系统提供的接口函数,引入 import os

import os
os.name# 返回操作系统类型
os.uname()#获取详细的系统信息
os.environ #返回环境变量
os.environ.get('key')#获取某个环境变量的值
os.path.abspath('.')# 查看当前目录的绝对路径:
os.path.join('/Users/michael', 'testdir')# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
os.mkdir('/Users/michael/testdir')# 创建一个目录:
os.rmdir('/Users/michael/testdir')# 删掉一个目录:
os.path.splitext(filePath)#直接得到文件扩展名
os.rename('test.txt', 'test.py')# 对文件重命名:
os.remove('test.py')# 删掉文件:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4. 序列化

变量从内存中变成可存储或传输的过程称之为序列化import pickle

d = dict(name='Bob', age=20, score=88)
pickle.dumps(d)
#返回b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'
f = open('a.txt', 'wb')
pickle.dumps(d,f)#把任意对象序列化成一个bytes
f.close()
pickle.loads(d)#反序列出对象d
f = open('a.txt', 'wb')
d=pickle.load(f)#从一个file-like Object中直接反序列化出对象
f.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

JSON

{} 表示python 中的dict类型,下同理
[] -> list
“string” -> str
1234.56 -> int或float
true/false -> True/False
null -> None

Python的json模块,引入import json

# Python对象变成一个JSON:
d=dict(name='Bob', age=20, score=88)
json.dumps(d) #返回'{"age": 20, "score": 88, "name": "Bob"}'
#JSON反序列化为Python对象,用loads()或者对应的load()
#方法前者把JSON的字符串反序列化,后者从file-like Object中读取字符串并反序列化
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
json.loads(json_str)#返回 {'age': 20, 'score': 88, 'name': 'Bob'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

JSON进阶

用class表示对象,比如定义Student类,然后序列化:

import json
class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
def student2dict(std):#自定义转换函数,转为dic类
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score
    }
s = Student('Bob', 20, 88)
print(json.dumps(s,default=student2dict))#使用自定义函数可成功转换
print(json.dumps(s, default=lambda obj: obj.__dict__))#把任意class的实例变为dict
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

把JSON反序列化为一个Student对象实例

def dict2student(d):
    return Student(d['name'], d['age'], d['score'])
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student)) #返回一个Student对象
  • 1
  • 2
  • 3
  • 4
  • 九、常用内建模块#

1. datetime

datetime是Python处理日期和时间的标准库,引入 from datetime import datetime

from datetime import datetime #from datetime import datetime导入的才是datetime这个类
now = datetime.now() # 获取当前datetime
print(now)
#结果 2020-06-23 16:28:07.198690
dt= datetime(2020, 6, 23, 16, 20) # 用指定日期时间创建datetime
print(dt)
#结果 2020-06-23 16:20:00
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

datetime转换为timestamp

把一个datetime类型转换为timestamp只需调用timestamp()方法,
Python的timestamp是一个浮点数。如果有小数位,小数位表示毫秒数。

from datetime import datetime
now = datetime.now()
print(now.timestamp())#结果 1592907913.290754
  • 1
  • 2
  • 3

datetime转换为timestamp

把timestamp转换为datetime,使用datetime提供的fromtimestamp()方法

from datetime import datetime
t =1592907913.290754
print(datetime.fromtimestamp(t))#2020-06-23 18:25:13.290754
  • 1
  • 2
  • 3

注:某些编程语言(如Java和JavaScript)的timestamp使用整数表示毫秒数,这种情况下只需要把timestamp除以1000就得到Python的浮点表示方法
UTC标准时间,和本地时间(北京时间)

from datetime import datetime
t =1592907913.0
print(datetime.fromtimestamp(t)) # 本地时间=UTC+8,
print(datetime.utcfromtimestamp(t)) # UTC时间=UTC+0
#结果
# 2020-06-23 18:25:13
# 2020-06-23 10:25:13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

str互相转换datetime

str转datetime,使用strptime()函数,’%Y-%m-%d %H:%M:%S’规定日期和时间部分的格式
datetime转str,使用strftime()函数,’%Y年%m月%d日 %H:%M:%S’可自定义规则输出字符串

from datetime import datetime
# str转datetime
cday = datetime.strptime('2020-6-20 18:19:59', '%Y-%m-%d %H:%M:%S')
print(cday) #返回 2020-06-20 18:19:59
# datetime转str
now = datetime.now()
print(now.strftime('%Y年%m月%d日 %H:%M:%S'))#返回 2020年06月23日 18:41:27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

datetime加减
对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime。加减可以直接用+和-运算符,不过需要导入timedelta这个类:

from datetime import datetime, timedelta
now = datetime.now()
print(now)
print(now + timedelta(hours=10))
print(now - timedelta(days=1))
print(now + timedelta(days=2, hours=12))
#结果
2020-06-23 18:50:12.885147
2020-06-24 04:50:12.885147
2020-06-22 18:50:12.885147
2020-06-26 06:50:12.885147
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2. collections
collections是Python内建的一个集合模块,提供了许多有用的集合类

namedtuple

namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素

from collections import namedtuple
Point=namedtuple('Point',['x','y'])
p=Point(1,2)
print(p.x)
print(p.y)
  • 1
  • 2
  • 3
  • 4
  • 5

deque

使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低,deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈,
deque除了实现list的append()pop()外,还支持appendleft()popleft(),这样就可以非常高效地往头部添加或删除元素。

from collections import deque
que=deque(['a','b','c'])
que.append('x')
print(que) # deque(['a', 'b', 'c', 'x'])
que.appendleft('y')
print(que)# deque(['y', 'a', 'b', 'c', 'x'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

defaultdict

使用dict时,如果引用的Key不存在,就会抛出KeyError**。如果希望key不存在时,返回一个默认值,就可以用defaultdict**

from collections import defaultdict
defdict=defaultdict(lambda :'N/A')
defdict['key1']='aaa'
print(defdict['key2']) #结果 N/A
  • 1
  • 2
  • 3
  • 4

OrderedDict

使用dict时,Key是无序的。在对dict做迭代时,无法确定Key的顺序,保持Key的顺序,可以用OrderedDict,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序
注:在3.6版本后,dict是有序的,默认为OrderedDict

from collections import OrderedDict
d=OrderedDict([('a', 1),('b', 2),('c', 3),('d', 4)])
print(d)
#结果 OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
  • 1
  • 2
  • 3
  • 4

Counter

Counter是一个简单的计数器,例如,统计字符出现的个数
Counterdict的子类

from collections import Counter
counter=Counter()
for chr in 'hello world':
    counter[chr]=counter[chr]+1
print(counter)#结果 Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
  • 1
  • 2
  • 3
  • 4
  • 5

3. base64

Base64是一种用64个字符来表示任意二进制数据的方法

Python内置的base64可以直接进行base64的编解码:

import base64
bin=base64.b64encode(b'abcdefghi')
print(bin) #结果 b'YWJjZGVmZ2hp'
get_bin=base64.b64decode(bin)
print(get_bin) #结果 b'abcdefghi'
  • 1
  • 2
  • 3
  • 4
  • 5

4. struct
Python提供了一个struct模块来解决bytes和其他二进制数据类型的转换

structpack函数把任意数据类型变成bytes
unpack把bytes变成相应的数据类型

import struct
print(struct.pack('>I', 10240099)) #>表示网络序,I无符号整数 #返回b'\x00\x9c@c'
print(struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80'))#后面的bytes依次变为I:4字节无符号整数和H:2字节无符号整数
  • 1
  • 2
  • 3

5. hashlib
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等

import hashlib
md5=hashlib.md5()
md5.update("abcdefg".encode('utf-8'))
print(md5.hexdigest())
#结果
7ac66c0f148de9519b8bd264312c4d64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的

import hashlib
md5=hashlib.md5()
md5.update("abcde".encode('utf-8'))
md5.update("fg".encode('utf-8'))
print(md5.hexdigest())
#结果
7ac66c0f148de9519b8bd264312c4d64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6. hmac
hmac模块实现了标准的Hmac算法,可使用hmac实现带key的哈希,不同的key会产生不同的hash,使加密更安全

import hmac
message=b'hello,world!'
key=b'secret'
h=hmac.new(key,message,digestmod='MD5')
#h.update("aaaa")#若消息很长,可以多次调用h.update
print(h.hexdigest())
#结果
fd3be58bca882f249670e2d597837f65
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

7. itertools
Python的内建模块itertools提供了用于操作迭代对象的函数。

itertools提供了几个“无限”迭代器,
count()会创建一个无限的迭代器,
cycle()会把传入的一个序列无限重复。
repeat()负责把一个元素无限重复下去,如果提供第二个参数就可以限定重复次数:

import itertools
natuals=itertools.count(1)
for n in natuals:
    print(n)#从1开始计数,
nns=itertools.takewhile(lambda x: x <= 10, natuals)#通过takewhile()等函数根据条件判断来截取出一个有限的序列:
print(list(nns))#结果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cs = itertools.cycle('ABC')
for c in cs:
    print(c) # 'ABC反复循环'
ns = itertools.repeat('A', 3)
for n in ns:
    print(n) # 'A'循环3次
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

itertools提供的几个迭代器操作函数

chain()

chain()可以把一组迭代对象串联起来,形成一个更大的迭代器

import itertools
for c in itertools.chain('ABC', 'XYZ'):
    print(c)
  • 1
  • 2
  • 3

groupby()

groupby()把迭代器中相邻的重复元素挑出来放在一起

import itertools
for key, group in itertools.groupby('AAABBBCCAAACCCC'):
    print(key, list(group))
#结果
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
C ['C', 'C', 'C', 'C']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 十、常用的第三方模块#

1. requests
requests是一个Python第三方库,以方便处理URL资源

import requests
r=requests.get('https://www.baidu.com/')
print(r.status_code) 
#结果 200
print(r.text) 
#结果 <!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type.... 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

带参数的URL,传入一个dict作为params参数:
需要传入HTTP Header时,传入一个dict作为headers参数
要发送POST请求,只需要把get()方法变成post(),然后传入data参数作为POST请求的数据

import requests
mparms={'wd': 'python'}
r=requests.get('https://www.baidu.com/s',params=mparms)
print(r.status_code)
print(r.url)
print(r.encoding)
print(r.content)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 十一、访问数据库#

1. 使用MySQL
需引入mysql.connector驱动包,这个包可能会失效,
可以使用pymysql

import pymysql
try:
    conn=pymysql.connect(host='47.115.80.162',port=3306, user='jiangzhiwei', password='jzw166998!', database='jiaowu', charset='utf8')
    cursor=conn.cursor()
    sql='create table user (id varchar(20) primary key, name varchar(20))'
    cursor.execute(sql)
    cursor.execute('insert into user (id, name) values (%s, %s)', ['1', 'Michael'])
    print(cursor.rowcount)
    cursor.execute('select * from user where id = %s', ('1',))
    values = cursor.fetchall()
    print(values)
except Exception:
    pass
finally:
    print(cursor.close())
    print(conn.close())
#结果
1
(('1', 'Michael'),)
None
None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/766995
推荐阅读
相关标签
  

闽ICP备14008679号