What did I learn when I finished learning Python~

In the past few days of learning Python, I feel that Python is relatively simple and easy to use, as far as the basic grammar is concerned, but some advanced features are still a bit difficult to master, and it takes time to digest. My biggest impression of Python is simplicity, which is one of the reasons why I don't like Java very much.

1. Introduction to Python

    Python is a high-level programming language used to write applications.

Python has achieved a strong counterattack, and I believe that with the passage of time, the future prospects of the domestic Python language are also promising.

    The characteristics of Python are elegant and simple, easy to learn and use (although I feel that there are still some concepts that are not easy to understand), the philosophy of Python is to use the least, most simple and easy-to-understand code to achieve the required functions. Python is suitable for developing network applications, script writing, daily simple gadgets and so on. The disadvantage of Python is that it is less efficient, but in a large number of occasions, efficiency is not that important or Python is not its performance bottleneck, so don't care too much. Secondly, the transition from 2.x to 3.x makes many 3.x lack many modules under 2.x, but it is also being perfected. The second is that the source code cannot be encrypted. Publishing a Python program is actually releasing the source code.

2. Basic grammatical points

1. If there are many characters that need to be escaped in a string, but you don't want to write so many '\', you can use r'...' to indicate that the content in '...' is not escaped.

2. Python can use '''...''' to represent multi-line content, such as:

1

2

3

4

5

6

>>> print('''line1

line2

line3''')

line1

line2

line3

3. Python's logical operations and, or, not correspond to &&, ||, ! in C language respectively.

4.Python's integer and floating point numbers have no range.

5. There are two types of division in Python: '/' must be a floating-point number, and '//' is an integer, that is, floor division.

6. Everything in Python is quoted. Each object has a reference counter (internal tracking variable) for tracking. The reference count value indicates how many references the object has. When it is assigned to the variable for the first time, the reference count is 1, and no one of the following behaviors is performed thereafter. Both will increase the reference count:

1

2

3

赋值:  a = b

用作函数参数传递: func(a)

成为容器对象的一个元素: lis = [1,2,a]

Any of the following actions will decrease the reference count:

1

2

3

4

del销毁: del a

变量另赋给其他对象:a = False

对象从容器中删除:  lis.remove(a)

身在的容器被销毁: del lis

7. The concept and comparison of deep copy and shallow copy 

8.list,tuple和dict,set

list: It is a list, which is an ordered collection, which is similar to an array but more powerful than an array. It can append and pop elements at any time. The subscript starts from 0, and the subscript is added n modulo n, that is, lis[-1] = lis[len-1], subscript range [-len,len-1].

tuple: It is a tuple, similar to a list, but the list is a variable type, while the tuple is immutable, that is, there are no functions such as append and pop. One suggestion is to use tuple instead of list for safety reasons and use tuple as much as possible. If the tuple has only one element, write it like (1,) to avoid ambiguity.

dict: dictionary type, which stores key-value key-value pairs, and can quickly find out the value according to the key. Of course, the key must be an immutable type. The following is wrong:

1

2

3

4

5

>>> dic = {[1,2]:'value'}

Traceback (most recent call last):

  File "<pyshell#10>", line 1in <module>

    dic = {[1,2]:'value'}

TypeError: unhashable type'list'

The advantages and disadvantages of list and dict:

1

2

3

4

5

6

7

dict:

   1.插入,查找速度快,跟key的数目无关

   2.需占用大量内存,内存浪费严重

list:

   1.插入,查找速度慢,O(n)的复杂度,随元素个数增加而增加

   2.占用内存小

The order in which the dict is stored has nothing to do with the order in which the keys are placed

set: set is similar to dict, which is equivalent to a dict with only key but no value. Each key is different. There are &, | and other operations between sets corresponding to the intersection of sets and operations.

3. Function

1. A function is an object, and the function name is a reference to the corresponding function object, so you can assign the function name to a variable, which is equivalent to giving the function an 'alias'.

1

2

3

>>> mmm = max

>>> mmm(1,2,3)

3

2. The Python function can return "multiple values". The reason why the quotation marks are used is because the multiple values ​​returned are actually combined into a tuple, and this tuple is returned.

3. Defining default parameters needs to be kept in mind: default parameters must point to immutable objects. Otherwise, the results of the first call and the second call will be different, because the variable default parameters have changed after the call.

4. Variable parameters: The number of parameters passed in is variable and can be 0 or more. Variable parameters will automatically assemble the parameters you pass in into a tuple. Adding a * before the name of the list or tuple you passed in means that the passed in is a variable parameter. The convention is *args.

5. Keyword parameters: Pass in 0 or more parameters containing parameter names, and these parameters will be automatically assembled into a dict. The habit of writing **kw, such as **a means that all key-value pairs in a are passed to kw in the form of keyword parameters, and a dict is obtained. This dict is a copy of a, and changes to kw will not be passed to a

6.命名关键字在函数定义中跟在一个*分割符后,如

1

2

def func(a,b,*,c,d):

    pass

c,d为命名关键字参数,可以限制调用者可以传入的参数名,同时可以提供默认值。

7.参数定义顺序:必选参数,默认参数,可变参数/命名关键字参数,关键字参数。

8.切片操作格式为lis[首下标:尾下标:间隔],如果都不填,即lis[::]则代表整个容器lis

9.用圆括号()括起来一个列表生成式创建一个生成器generator,generator保存生成算法,我们可以用next(g)取得生成器g的下一个返回值。生成器的好处就是我们不需要提前生成所有列表元素,而是需要时再生成,这在某些情况下可以节省许多内存。算法也可以不是列表生成式而是自定义函数,只需在函数定义中包含yield关键字。

10.map()和reduce(): 二者都是高阶函数。map()接收两个参数,一个是函数,一个是Iterable序列,map将传入的函数依次作用在序列每一个元素上,并把结果作为新的Iterator返回。reduce()类似累积计算版的map(),把一个函数作用在一个序列上,每次接收两个参数,将结果继续与序列的下一个元素做累积计算。

利用map和reduce编写一个str2float函数,如把字符串'123.456'转换成浮点数123.456:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from functools import reduce

def str2float(s):

    def f1(x,y):

        return x*10 + y

    def char2num(s):

        return { '0'0'1'1'2'2'3'3'4'4'5'5'6'6'7'7'8'8'9'9}[s]

    def f2(x,y):

        return x*0.1 + y

    a,b = s.split('.')

    print('a=',a)

    print('b=',b)

    return reduce(f1, map(char2num,a)) + 0.1*reduce(f2, map(char2num,b[::-1]))

print('str2float(\'123.456\') =', str2float('123.456'))

11.fliter()函数过滤序列,类似于map()作用于每一元素,根据返回值是True或者False决定舍弃还是保留该元素。函数返回一个Iterator。

12.sorted()函数可实现排序,类似于C++库中的sort()函数,但是比其更加简洁,语法为sorted(lis,key=func,reverse=T/F)

key函数可实现自定义的排序规则,reverse表示升序还是降序。

13.一个函数可以返回一个函数,但是返回时该函数并未执行,所以返回函数中不要引用任何可能发生变化的变量,否则会出现逻辑错误。

14.装饰器(decorator): 当需要增强函数的功能却不希望修改函数本身,那么可以采用装饰器这种运行时动态增加功能的方式,增加的功能卸载装饰器函数中。如在执行前后打印'begin call'和'end call',可以这样做:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import functools

def log(func):

    @functools.wraps(func)     #为了校正函数签名,最好写上

    def wrapper(*args,**kw):

        print('begin call')

        = func(*args,**kw)

        print('end call')

        return f

    return wrapper

@log

def hah():

    print('hahahaha')

hah()

1

2

3

begin call

hahahaha

end call

15.偏函数: functools.partial(),作用是将一个函数的某些参数固定住,作为新函数的参数,即固定住该参数,返回一个新函数,使调用更简单。

四、面向对象编程

1.Python实例变量可以自由地绑定任何属性

2.为了不让内部属性不被外部访问,在属性的名称前加上两个下划线__,这样就变成了一个私有变量(private),注意,不能直接访问不代表一定不能访问,事实上,加双下划线后Python就会将其改名为‘_class名__name’,所以还是可以这样来访问这个‘私有’变量。

3.对于静态语言,如果要求传入一个class类型的对象,那么传入的对象必须是class类型或者其子类,否则将无法调用class中的方法,而Python这样的动态语言有‘鸭子类型’一说,即不一定要传入class类型或其子类,而只要保证传入的对象中有要使用的方法即可。

4.如果想要限制实例可以绑定的属性,那么在定义class时定义一个__slots__变量即可,例如:

1

2

class Student(object):

    __slots__ = (‘name’,’age’)

注意,__slots__限制的属性对当前类实例起完全限制作用,且与子类共同定义其__slots__,也就是说子类可以定义自己的__slots__,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__,即并集。

5.@ property装饰器可以使一个getter方法变成属性,如果方法名为me,那么@me.setter装饰器则可使一个setter方法变成属性。这样可以使代码更简短,同时可对参数进行必要的检查。

6.通过多重继承,可使子类拥有多个父类的所有功能。

7.在类中__call__方法可使实例对象像函数那样直接调用,作用即是该方法定义的过程。

8.ORM(Object Relational Mapping 对象关系映射),就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表。ORM的实现需要通过metaclass元类修改类的定义。元类可以改变类创建时的行为。

五、调试

1.Python调试方法:

    (1)直接打印

    (2)断言

    (3)pdb

    (4)IDE

六、IO编程

1.序列化: 把变量从内存中变成可存储或传输的过程称之为序列化。Python用pickle模块实现序列化。序列化之后,就可以把序列化后的内容存储到磁盘上或者通过网络进行传输。pickle.dumps()将对象序列化成一个bytes,而pickle.loads()可以根据bytes反序列化出对象。

2.pickle虽好,但是它专为Python而生,所以要在不同语言间传递对象,最好还是xml或者json,而json表示格式是一个字符串,更易读取,且比xml快,所以更加适宜于对象序列化。Python内置了json模块,相应方法仍然是dumps()和loads()。

3.但是在默认情况下,有些对象是无法序列化的,所以我们有时还需要定制转换方法,告诉json该如何将某类对象转换成可序列为json格式的{}对象。如下即是一个转换方法:

1

2

3

4

5

6

def mantodict(std):

    return {

        'name': std.name,

        'age': std.age,

        'id': std.id

    }

七、进程与线程

1.Python用mutiprocessing模块来实现多进程。

2.如果要大量创建子进程,可以使用进程池:

1

from multiprocessing import Pool

示例如下:

1

2

3

4

5

6

7

8

....

    = Pool(4)

    for in range(5):

        p.apply_async(long_time_task, args=(i,))

    print('Waiting for all subprocesses done...')

    p.close()

    p.join()

    print('All subprocesses done.')

要使用进程池需新建Pool对象,对Pool对象调用join()使等待池中所有子进程运行完毕,调用join()方法之前必须调用close(),且此后无法再新加子进程。

3.使用subprocess模块可以方便的启动并管理一个子进程,控制其输入输出。

4.进程间通信使用Queue,Pipes实现。

5.threading模块管理线程。threading.lock()创建线程锁,防止同时访问互斥资源造成的错误,示例如下:

1

2

3

4

5

6

7

lock = threading.Lock()

...

lock.acquire()

...

change(mutex)

...

lock.release()

6.ThreadLocal可以解决参数在一个线程中各个函数之间互相传递的问题。

7.managers模块实现分布式进程。

八、正则表达式与常用内建模块

1.re模块进行正则表达式编译和匹配,如果该表达式需要匹配很多次,那么最好进行编译从而大大节省时间。

正则表达式匹配邮箱例子:

1

2

3

4

5

6

7

8

9

10

import re

hah = re.compile('[0-9a-zA-Z]+[\.[0-9a-zA-Z]+]*\@[0-9a-zA-Z]+\.[a-z]{2,3}')

print(hah.match('[email protected]').group())

print(hah.match('[email protected]').group())

= 1

while i < 10:

    = input('请输入邮箱:')

    print(hah.match(r).group())

    = i+1

2.datetime模块进行日期和时间的处理,每一个时间对应一个timestamp,我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp。字符串和datetime也可以相互转换,采用strptime()方法,字符串转换为datetime时需要设定一个识别格式,其中

1

%Y-%m-%%H:%M:%S

分别表示年-月-日 时-分-秒。

从datetime得出月份,星期等字符串用strftime()方法,其中:

1

%a, %%%H:%M

分别表示星期, 月份 日期 时:分。

示例:

1

2

3

4

5

6

7

8

9

10

from datetime import datetime

= '2015-11-23 12:01'

dt = datetime.strptime(r, '%Y-%m-%d %H:%M')

print(dt)

week = dt.strftime('%a %b %d, %H:%M')

print(week)

2015-11-23 12:01:00

Mon Nov 2312:01

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

4.Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。

5.struct模块用来解决bytes和其他二进制数据类型的转换。

6.Python的hashlib提供了常见的哈希算法,如MD5,SHA1等等。hashlib实现简单登录:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

import hashlib

db = {

    'michael''e10adc3949ba59abbe56e057f20f883e',

    'bob''878ef96e86145580c38c87f0410ad153',

    'alice''99b1c2188db85afee403b1536010c2c9'

}

def get_md5(ostr):

    md5 = hashlib.md5()

    md5.update(ostr.encode())

    return md5.hexdigest()

def login(user, password):

    = get_md5(password)

    for name in db:

        if db[name] == r:

            return True

    return False

print(login('bob','abc999'))

True

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

8.urllib提供了一系列用于操作URL的功能。如GET,POST...

9.PIL(Python Imaging Library Python图像库)是一个强大的图像处理标准库,功能强大却又简单易用。现在的名字叫做Pillow。可以如下安装Pillow:

1

pip3 install pillow

从下面生成数字验证码的程序可以窥其一斑:

from PIL import Image, ImageDraw, ImageFont, ImageFilter

import random

# 随机字母:
def rndChar():
    return chr(random.randint(48, 57))

# 随机颜色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))

# 随机颜色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 创建Font对象:
font = ImageFont.truetype('ariblk.ttf', 40)
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 填充每个像素:
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=rndColor())
# 输出文字:
for t in range(4):
    draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')

效果:

九、网络编程和电子邮件

1.网络编程主要是TCP和UDP的编程

2.SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。Python对SMTP支持有smtplibemail两个模块,email负责构造邮件,smtplib负责发送邮件。Python内置一个poplib模块,实现了POP3协议,可以直接用来收邮件。由于现在绝大多数大型邮件服务商都采取了反垃圾邮件措施,所以这部分的简单实验并没有成功,还需进一步研究,等遇到具体情况再说。

3.Python内嵌了sqlite数据库,还可以自行安装连接mysql,MySQL是当前最流行的开源数据库,在行业内有着广泛的应用。

十、Web开发和异步IO

1.WSGI(Web Server Gateway Interface) 服务器网关接口。

2.Python web 开发框架:

    -Flask:流行的Web框架

    -Django:全能型Web框架

    -web.py:一个小巧的Web框架

    -Bottle:和Flask类似的Web框架

    -Tornado:Facebook的开源异步Web框架

3.协程

Guess you like

Origin blog.csdn.net/m0_72557783/article/details/128428388