Python3入门与进阶【笔记】

1、二、八、十六进制转十进制:int('10', base=2)、int('10', base=8)、int('10', base=16);

2、八、十、十六进制转二进制:bin(0o+xxx)、bin(xxx)、bin(0x+xxx);

3、二、十、十六进制转八进制:oct(0b+xxx)、oct(xxx)、oct(0x+xxx);

4、二、八、十进制转十六进制:hex(ob+xxx)、hex(0o+xxx)、hex(xxx);

5、“/”除法,结果转化为float;“//”整除;

6、序列:列表list,元组tuple,字符str   特点:有序

  无序:集合set,字典dict

  集合set的去重性:{1,1,2,2,3,3}  -------> {1,2,3};求两个集合的差值:{1,2,3,4,5,6} - {3,4}  ---->  {1,2,5,6};求两个集合共有元素:{1,2,3,4,5,6} & {3,4}  -----> {3,4};合并:{1,2,3,4,5,6} | {3,4,7} --------> {1, 2, 3, 4, 5, 6, 7};

7、字符串不可改变

   A = ‘hello’

  A = A + ‘python’

  此时A的地址已经改变了

8、关系运算符==” 比较两个值是否相等

a = 1, b = 1.0  a == b --------->True

身份运算符is”  比较两个变量身份是否相等(理解为内存地址是否相等)

a = 1, b = 1.0  a is b --------->False

9a = ‘hello’

Isinstance(a, (int,str,float)) 判断a是否为后面这三种类型的其中一种

10、通过from  .模块  import  *”可以导入所有变量,函数。但我们在被导入的模块里的开头加上“__all__ = [‘变量名’, ‘变量名’, ‘变量名’]”,这样导入的时候就不是导入全部,而是指定的变量名了

用括号进行换行,不要用反斜杠””

11、什么是函数?

1、功能性(实现某个功能)

2、隐藏细节

3、避免编写重复的代码

def damage(skill1, skill2):

  damege1 = skill1 * 3

  damege2 = skill2 * 2 + 10

  return  damege1, damege2

damages = damage(3, 6)

注意,返回的damages是一个元组。

取出里面的值可以通过damages[0], damages[1],但不推荐这种方法。

我们可以用两个变量来接收返回结果。(用有意义的变量来接收,有益于维护)

eg:skill1_damage, skill2_damage = damage(3, 6)

12、序列解包

d = 1, 2, 3

type(d) -------> <class ‘tuple’>

a, b, c = d (等于 a, b, c = (1, 2, 3))(注意,元素个数要相等)

print(a, b, c) ----------> 1, 2, 3

13、函数的参数有三种:形参、关键字参数、默认参数

默认参数要放在必须参数后面(要用户自己填入的参数叫必须参数)。调用的时候也一样。

Egdef t_student_files(name, gender='', age=18, college='光明路小学', teacher):      错误

...     pass

---------------------------------------------------------------------------------

def t_student_files(name, gender='', age=18, college='光明路小学'):

...     pass

t_student_files('渣渣',gender='', age=17, college='佛山科学技术学院')     正确

t_student_files('渣渣','', 17, '佛山科学技术学院')   正确

t_student_files('渣渣',gender='', 17, college='佛山科学技术学院')         错误(这时候17会被认为是必须参数)

14、面向对象

变量的名字可以用下划线_“来连接,但类的名字最好不要,两个单词首字母大写即可 eg: class StudentHomework()

类最基本的作用:封装

类是现实世界或思维世界中的实体在计算机中的反应

它将数据以及这些数据的操作封装在一起

类里面有:特征(用变量或数据成员表示) + 行为(用方法表示)

15、

class Student():

  name = ‘’

  age = 18

  def print_file(self):

    print(“name:”,self.name)

    print(“age:”,self.age)

注意,为了打印出nameage,必须要用self.name,self.age

同时,不能在类里面调用函数,例如:

“””

class Student():

  name = ‘’

  age = 18

  def print_file(self):

    print(“name:”,self.name)

    print(“age:”,self.age)

  print_file()

”””

因为类只负责定义,不负责运行。

# 方法和函数的区别

其实一般没有什么区别,非要说的话,就是

方法:设计层面 (类里面称方法)

函数:程序运行、过程式的一种称谓 (在模块里称函数)

同样,对于变量,在模块里叫变量,在类里面叫数据成员

16、

class Student():

  name = ‘’

  age = 18

  def __init__(self):  # 构造函数

    print(“student”)

  def print_file(self):

    print(“student”)

student = Student()  

student.print_file()

# 将打印两个”student”,一个是实例化时student.__init__() 自动调用的,一个是显示调用”print_file()”生成的

17、

class Student():

  name = ‘’

  age = 18

  def __init__(self):  # 构造函数

    print(“student”)

  def print_file(self):

    print(“student”)

student = Student()

a = student.__init__()

print(type(a))

a的类型为None,当在后面加上return None的时候,编译不报错

eg:class Student():

  name = ‘’

  age = 18

  def __init__(self):  # 构造函数

    print(“student”)

    return None

  def print_file(self):

    print(“student”)

student = Student()

a = student.__init__()

print(type(a)) ----------> None

但改为return “student”时,编译报错,说明def __init__()也就是构造函数只能返回None类型,不能是字符串啥的,这是和其他函数的区别

18、

class Student:

     name = 'qiyue'

   age = 0

     def __init__(self, name,age):

         name = name

         age = age

     def func(self):

         print("name:",self.name)

student1 = Student('石敢当', 18)

print(student.name) ---------> qiyue

为什么会打印出”qiyue”呢,首先我们把值传进去,但没有实例对象来接收,这时实例对象是空值(可以用print(student1.__dict__)验证)python知道我们要输出实例对象的值,首先去实例对象里面寻找,当没有时,继续往上一级,找到类变量,然后输出。

self, 定义实例方法时必须传进,显示指定。类似其他语言的this

self就是当前调用某一个方法的对象

Eg: student1 = Student(‘石敢当’, 18)

student1.do_homework()

此时do_homework()里的self指的就是student1。那么前面的self.name = name就很好理解了,相当于“实例对象.name = name”。

实例方法是和对象实例相关联的,必须传入self

19、

思考题:

class Student:

     def __init__(self, name,age):

         self.name = name

      name = name

        print(self.name)

        print(name)

     def func(self):

        pass

student1 = Student('石敢当')

注意,打印出来都是相同的名字,但第一个打印出来的是实例化变量,第二个只是把形参打印出来了。如果把形参改为name1,下一个改为self.name=name1,其他不变。那么第二个将报错。说明print(name)并不是打印出实例参数。

20、

在实例方法里面访问类变量的方式:

1、class Student:

     num1 = 0

       def __init__(self, name,age):

           print(Student.num1)

2、class Student:

     num1 = 0

       def __init__(self, name,age):

           print(self.__class__.num1)  #__class__指代类Student

21、如何在类方法里操作类变量

class Student:

     def __init__(self, name,age):

    sum = 0

         self.name = name

         self.age = age

   # self.__class__.sum += 1

  @classmethod

  def plus_sum(cls):  #cls代表调用的类

    cls.sum += 1

    print(cls.sum)

student1 = Student('石敢当', 18)

Student.plus_sum()  # 建议这种

student1.plus_sum()

student2 = Student('敢当', 18)

Student.plus_sum()

student3 = Student('', 18)

Student.plus_sum()

22、静态方法(可以被对象或者类调用):

class Student:

     def __init__(self, name):

         self.name = name

     def func(self):

       pass

 @staticmethod

    def add(x, y):  

     pass

没有self,cls的传入,可以访问类变量,不能访问实例变量(类方法也是

23、公开和私有的概念:

通过”__方法或__变量”,表示这是私有的,不能从外部直接访问。

但是,你会发现这个操作竟然是可以运行的:

class Student:

     def __init__(self, name):

         self.name = name

    self.__score = 0

student1 = Student(“石敢当”)

student1.__score = -1    

为什么此时直接对”__score”赋值还是可以的呢?因为这是python动态语言的特性,此时不是真的对私有变量”__score”进行修改,而是python重新创造了一个新的普通变量”__score”。而原来那个私有变量其实会被自动改为”_Student__score”。

24、继承

如何在子类的构造函数里调用父类的构造函数

class Human():

  def __init__(self, name, age):

    self.name = name

    self.age = age

class Student(Human):

  def __init__(self, school, name, age):

  self.school = school

  Human.__init__(self, name, age) # 注意,这里要把nameage传进去,直接调用Human.__init__方法就行,但是记住self不能省略,因为这时和我们实例化对象时去调用构造函数是截然不同的,那个是用对象来调用,就不用加self,因为对象此时就是self。但这里就是相当于一个普通方法的调用,因此需要把参数都传进去。

更好的方法,用super,这样一旦父类改变了,不用修改子类中的代码

class Student(Human):

  def __init__(self, school, name, age):

    self.school = school

    super(Student, self).__init__(name, age)

25、正则表达式与JSON

“Python” 普通字符        “d” 元字符

#字符集

w 单词字符,不能是空格  # 除单词外其他所有W

s 空白字符

. 匹配除换行符之外所有字符,包括空格, 不包括

Import  re

s = “abc, acc, acb, aec, afc”

r = re.findall(‘a[c-f]c’, s)  匹配中间字符是cf

r = re.findall(‘a[^cf]c’, s)  匹配中间字符不是cf

r = re.findall(‘a[cf]c’, s)  匹配中间字符是cf

注意,匹配只能匹配单一的字符,因此输出结果都是一个个分开的字符

26、#数量词 {数字}

* 匹配0次或者无限多次

+ 匹配1次或者无限多次

?匹配0次或者一次

a = “python java111php”

r = re.findall(‘[a-z]{3}’, a)  --------->[‘pyt’,’hon’, ‘jav’, ‘php’]

贪婪:r = re.findall(‘[a-z]{3, 6}’, a) ----------->[‘python’,’java’,’php’]

非贪婪:r = re.findall(‘[a-z]{3, 6}?’, a) --------->[‘pyt’,’hon’, ‘jav’, ‘php’]

27、 (要匹配的字符)

a = ‘PythonPythonPythonPythonPython’

r = re.findall(‘Python{3}’, a) # 这种只能表示要”n”出现3次,如果想要匹配Python出现3次,写成r = re.findall(‘(Python){3}’, a)

[abc]中括号里面字符是”或”关系,(Python)小括号里面字符是”且”关系

28、模式参数

r = re.findall(‘python’, a, re.I)  #让正则表达式的作用忽略大小写

r = re.findall(‘python’, a, re.I | re.S)  #匹配所有字符包括换行符

29、替换 sub

 l = “pythoncjavac#phpc#”

r = re.sub(“c#”, “go”, l) # 都替换

r = re.sub(“c#”, “go”, l, 1) # 替换一次

l.replace(“c#”, “go”)  # 内置函数,不过这样是没有结果的,因为字符串不可改变,要改成language=l.replace(“c#”, “go”)

sub的强大之处在于第二个参数可以传递函数

def convert(value):

  matched = value.group()  # c#作为值传递给value后,是一个对象,不能直接取出来

return “!!”+matched+”!!”  # 返回的是字符串

r = re.sub(“c#”,  convert,  l)

30、match() search()

match()是从字符串首位开始,如果首位不是要匹配的值就返回None,search()是找到一个就返回一个对象,结束匹配。用group()取出来。

31、s = ‘life is short, I use python’

如何取中间的字符?

r = re.search(‘life(.*)python’, s) # 不能用/w,因为识别不出空格

print(r.group(1)) --------> ‘is short,I use’

注意,用print(r.group(0))永远输出’life is short, I use python’,即不分组所匹配到的最原始那个

print(r.groups())就只会返回用括号括起来的结果

r = re.findall(‘life(.*)python’, s)  # findall直接输出

print(r[0])(返回结果是列表) --------> ‘is short,I use’

32、JSON

一种轻量级的数据交换格式

应用场景:网站后台——》浏览器

JSON是和语言无关的,跨语言的,在每个语言中几乎都可以找到和它对应的数据结构,例如python中的字典,我们要做的就是把JSON转化为其中的字典,这样操作起来就容易的多。

import json

json_str = ‘{“name”:”qiyue”, “age”:18}’ # 格式是里面的字符串必须要加引号,而且是双引号

student = json.loads(json_str)

这样一个JSON对象‘{“name”:”qiyue”, “age”:18}’ 称为JSON object,对应到python里面就是字典。还有一种是JSON arrey(数组),例如’[{“name”:”qiyue”, “age”:18}, {“name”:”qiyue”, “age”:18}] ‘,对应python的列表。

布尔值在JSON里用小写的false表示,‘{“name”:”qiyue”, “age”:18, “flag”:false}’

反序列化:由字符串到某种语言的数据结构

序列化:json.dumps()

33、枚举 (python里是一个类)

from enum import Enum

class VIP(Enum):

  YELLOW = 1

  GREEN = 2

  BLACK = 3

  RED = 4

用枚举的方式表示类型1234,可读性好很多

print(VIP.YELLOW)  ---------> VIP.YELLOW

枚举的意义重在它的标签,而不是它的数值

用字典和类表示枚举的缺点:

1、可变   2、没有防止相同值的功能

获取枚举数值

print(VIP.YELLOW.value) --------> 1

获取枚举标签名字

print(VIP.YELLOW.name) --------> YELLOW --------> <class ‘str’>

print(VIP.YELLOW)  ---------> VIP.YELLOW --------> <enum ‘VIP’>

print(VIP[‘YELLOW’]) --------> VIP.YELLOW 通过枚举名称获得名称对应的枚举类型

34、枚举的比较

result = VIP.YELLOW == 1

print(result) --------> False

result = VIP.YELLOW == VIP.GREEN 可以进行等值比较

print(result) --------->False

result = VIP.YELLOW > VIP.GREEN 报错 不能进行大小之间的比较

result = VIP.YELLOW  is  VIP. YELLOW 可以进行身份比较

print(result) --------->Ture

注意事项

枚举标签不可以一样,但值可以,只是这时第二个相同的数值相当于第一个的别名,打印它会打印出第一个的标签

class VIP(Enum):

  YELLOW = 1

  GREEN = 1

  BLACK = 3

  RED = 4

print(VIP.GREEN) ----------> YELLOW # 此时GREEN相当于YELLOW的别名,不会是个独立的枚举,遍历的时候不会打印出来,如果非要遍历别名,用“__members__.items()

for v in VIP.__members__:

  pass

35、写成代码的话,用枚举的类型表示,存进数据库,用枚举的值。然后当从数据库取出数值时,怎么关联到枚举类型呢?eg: 取出 a = 1print(VIP(a)) --------> VIP.YELLOW

36、闭包

闭包 = 函数 + 环境变量(函数定义时候)

eg:

def curve_pre():

  a = 10  # 环境变量

  def curve(x):  # 函数

    return a*x*x

  return curve

f = curve_pre()

环境变量保存在f.__closure__”里

闭包的意义,保存的是一个环境,也就是把函数调用时的现场保存下来

闭包常见误区,就是内部函数引用变量a时,不能给它赋值,可以用a来进行计算,但不能赋值,否则python认为它是一个局部变量,此时闭包也就不存在了。

def f1():                           def f1():

  a = 10                 a = 10

  def f2():         def f2():

    c = 20 * a       a = 20

  return f2       return f2

f = f1()  f是闭包     f = f1() f不是闭包

 37、实现一个记步数的问题中,先用非闭包的方式实现

origin = 0

def go(step):

  new_step = origin + step

  origin = new_step

  return new_step

print(go(2))  注意,此时会报错,显示origin还没有定义,为什么会这样呢?不是说好当在函数内找不到origin定义时,会自动往上一级去寻找吗?其实这里主要是因为下面那句“origin = new_step”,因为加了这句,python就会把origin当作一个局部变量来处理,所以这时才会出错,解决办法是在函数里面最开始加上”global  origin”。

38、闭包实现:

origin = 0

def factory(pos):

  def go(step):

    nonlocal pos  # 声明不是当地局部变量

    new_step = pos + step

    pos = new_step

    return new_step

  return go

tourist = factory(origin)   print(tourist(2))

闭包相对于引入全局变量的好处是不会修改全局变量的值

 39、 函数式编程

匿名函数

egdef add(x, y):           ==           lambda x,y: x+y

    return x+y

调用:add(1,2)           f = lambda x,y: x+y   f(1, 2)

匿名函数冒号后面只能是表达式(像a=x+y这种属于赋值语句了),而且只能是简单的语句

 40、python中的三元表达式

格式:

条件为真时返回的结果 if 条件判断 else 条件为假时返回的结果

 eg:print(1+2 if 2 > 1 else 666)

 41、map 函数 

list_x = [1,2,3,4,5,6]

def square(x):

  return x * x

r = map(square, list_x )  # 映射,把原来列表里面的值映射到新的返回结果

print(list(r))

42、map lambda表达式的结合:

r = map(lambda x: x*x, list_x)

43、reduce

reduce  接受的参数一定要是两个

连续计算,连续调用lambda

from functools import reduce

list_x = [1,2,3,4,5,6,7,8]

r = reduce(lambda x,y: x+y, list_x) # 这里和map不同的地方就在于虽然有两个参数,但可以只传一个列表,一开始是x=1y=2,然后相加等于3,赋值给x,然后y等于下一个数值3,以此类推

print(r)  ---------36   # 这里不用list(r)

相当于((((1+2)+3)+4)+5)...

r = reduce(lambda x,y: x+y, list_x, 10)

结果返回46,过程不是因为最后得出36再和10相加,而是一开始把10作为初始值参与到计算里面。

44、filter

特点:lambda表达式返回结果是可以判断真假的(10TrueFalse)

list_ x = [1,0,1,0,1,0]

r = filter(lambda x: x, list_x) # 根据返回结果真假选择是否保留

print(list(r)) -------> [1,1,1]

45、装饰器

支持传递一个参数的装饰器

import time

def decorator(func):

  def wrapper(func_name):

    print(time.time())

    func(func_name)

  return wrapper

 

@decorator

def f1(func_name):

  print(“This is a function named ” + func_name)

f1(‘test_name’)

 

更好的解决办法,可以接收任意多个参数的是

import time

def decorator(func):

  def wrapper(*args):

    print(time.time())

    func(*args)

  return wrapper

可以接收关键字参数

import time

def decorator(func):

  def wrapper(*args, **kw):

    print(time.time())

    func(*args,**kw)

  return wrapper

 

@decorator

def f1(func_name1, func_name2, **kw):

  print(“This is a function named ” + func_name1)

  print(“This is a function named ” + func_name2)

  print(**kw)

 

f1(‘test_name1’,‘test_name2’, a=1, b=2, c=3)

 46、模仿C语言中的switch

用字典来代替switch

day = 0

switcher = {

  0 : ‘Sunday’,

  1 : ‘Monday’,

  2: ‘Tuesday’

}

day_name = switcher[day]

print(day_name)

但这样是不能满足有默认值的情况的,因此修改为用内置函数get()方法来获取

day_name = switcher.get(day, ‘Unknow’) # 容错性

 

进一步,考虑可以加代码块的情况,因此修改为

day = 0

def get_Sunday():

  return Sunday

def get_Monday():

  return Monday

def get_Tuesday():

  return Tuesday

def get_default():

  return “Unknow”

switcher = {

  0 : ‘get_Sunday’,

  1 : ‘get_Monday’,

  2: ‘get_Tuesday’

}

day_name = switcher.get(day, get_default)() # 加括号

 47、列表推导式

 a = [1,2,3,4,5,6,7,8]  a列表每个元素的平方

之前的知识,map()函数

r = map(lambda x:x * x, a)

>>> print(list(r))

[1, 4, 9, 16, 25, 36, 49, 64]

 

列表推导式

 l = [x**2  for  x  in a]

>>> print(l)

[1, 4, 9, 16, 25, 36, 49, 64]

another:  l = [x**2  for  x  in  a  if  x > 5]

当把括号换成中括号之后,输出的就是集合,以此类推,因此:集合,元组,字典都可以被推导

字典如何编写列表推导式

students = {

  ‘喜小乐’:18,

  ‘石敢当’:20,

  ‘横小五’:15

}

b  =  {value:key  for key, value in students.items()} # 记得加.items(),不然报错

b  =  (key  for key, value in students.items())

for x in b:

  print(x)    # 当用列表推导式计算元组时,结果b是一个generator对象,不能直接打印,只能遍历

原文地址:https://www.cnblogs.com/linyuhong/p/9969819.html