python学习笔记(推荐有其他语言编程经验想学python的人看)

文章目录

  • 进制转换
  • 身份判断:
  • 注意: isinstance() 可以判断父类和子类相等
  • 算术符号的优先等级
  • 导包的方法
  • 导入多个模块变量或者方法
  • __init__.py的用法
  • 内置函数
  • 注意: 自定义函数名, 不要和 内置函数重名
  • *** 递归调用的次数可以自己设置, 通过sys库
  • 返回值类型为多个时的处理方式
  • 序列解包
  • 参数
        • 注意: 关键字参数 和 默认参数 不能和普通参数有交叉, 有混杂的使用的
  • 面向对象
      • 类定义
  • 局部变量不会覆盖全局的变量
  • 理解类变量和实例变量的区别
  • python中的类变量和实例变量的表示
  • 查看类 或者 对象中所有属性的方法
  • 类中如何访问类变量
  • 什么时候使用类方法 什么时候 使用静态方法
  • 装饰器 初了解
  • python中的私有变量 和 私有方法
  • python中没有绝对意义上的私有变量(包括 实例变量和 类变量) 和 私有方法
  • python 中的继承, 构造方法, 使用父类的特点
  • 如何使用 父类 中的其他方法
  • 正则表达式
    • 常用正则
      • 字符集匹配
    • 概括字符集
    • 数量词
      • 贪婪与非贪婪
      • *匹配0次, 或者无限多次
    • 边界匹配
    • 匹配模式
    • re.sub 替换匹配项 的用法(函数)
    • search 和 match 的区别
    • 分组 () 的高级使用
    • group() 与 groups() 的使用
    • 什么情况下使用正则 什么情况下 使用内置函数
  • JSON (JavaScript Object Notion) JS 对象标记语言
    • JSON 的本质
    • !! JSON指一种数据格式
    • 字符串是 JSON 的
    • JSON 字符串: 符合JSON格式的字符串
    • JSON 优点
  • 对于JSON的 见解
    • JSON 以一种与 语言无关的语言, 因此 它的 格式不管在什么语言中表示, 都是相同的格式, 每种语言中都会有相应的JSON语言的映射 JSON | python
    • 序列化 与 反序列化
    • JSON对象. JSON. JSON字符串 ???
    • JSON 存在的意义
  • 枚举类型
      • 枚举的替代品
      • 正确的使用枚举
      • 获取枚举类型的值 或者 标签
      • 枚举类型的遍历
      • 枚举的比较 和 判断 是否是同一个枚举
      • 枚举常见的错误和误区
      • 如何将数值类型转换成枚举类型
      • 如何避免枚举类型 标签 值相同的问题 或者说 类型相同的问题
  • 是否需要学习 设计模式( 对于设计模式的见解 )
  • python 一切皆对象
  • 函数式编程
      • 闭包函数
      • 闭包到底有什么用, 在什么时候用
      • 安全性的思考
      • 函数式编程的思考
      • 匿名函数
      • python 的三元表达式 ( 使用lambda合适)
      • map的使用 (配合 lambda 来使用, 循环处理数据)
      • reduce 的使用 ( 连续计算 )
      • filter 的用法 (过滤器, 判断是否时英文句子的开头, 过滤大小写)
      • 函数式编程与命令式编程的区别
  • 装饰器
          • 思考
      • 装饰器 通用形式 加了 *args
      • 装饰器 全通配函数形式, 增加 **kw
  • 关键字参数
  • 网络爬虫
  • python 杂记
      • 用 dict 代替 switch
      • 推导式 (列表, 集合, 字典))
      • None 不等于 [] False ''
      • 并不是一个创建的对象, bool(Object) 一定是 True
      • bool() 方法, 实质是调用了对象中的某些方法
      • len() 方法, 实质是调用了对象中的__len__() 方法

进制转换

ord() ----> 将ascll码 转换成数字

数值类型 tuple(1,2,3) str int
引用类型 list [1,2,] dict {1,2,} set {1,2,}

以上的类型都可以进行加 和 乘

hex() 0x
oct() 0o
bin() 0b

id() 获取地址

多行字符串

关系运算

身份判断:

is 地址判断
is not

注意: isinstance() 可以判断父类和子类相等

type() == type 不行
isinstance(a, type)

isinstance(a, (int, str, float)) 判断a是否是 后面类型中的一种

type

二进制的位运算符号

算术符号的优先等级

算术(+, -, *, /) > 比较( >=, <, >) > 等于(==, <>, !=) > 赋值(=, +=, -=, *=) >
身份(is, is not) > 成员运算(in, not in) > 逻辑(not, and, or)

for i in dict:

else:
异常结束的话, 不会执行

for x in range(10, 0, -2):
print(x, end())

导包的方法

import t.zd
使用 t.zd.a

方法二:
import t.zd as m
使用 m.a

方法3:
from t.zd import a
使用 a

方法4:
from t.zd import *
使用 a

方法5:
from t import zd
使用: zd.a

问题: 不需要导入那么多 没有引用到的变量 或者 方法

在被导入的模块中加入
all = [‘a’, ‘b’, …] 限制通过* 被到导出的变量

导入多个模块变量或者方法

from 模块名 import (a,b,c,
d,e,f)

这种方式可以换行来处理, 导入模块的方式

init.py的用法

包的批量导入的方法

在__init__.py文件中, 预先导入相关的包, 就不用后续来导入的相关的包

在__init__.py文件中, 添加 all = [‘模块明’] 来限制, 外部通过, from 模块/变量 import * 导入的模块或者包的类型, 和变量

** 注意 要避免循环引用包 的方法
文件1 引用 文件2
文件2 引用 文件1

内置函数

round(数字, 保留小数的位数)

注意: 自定义函数名, 不要和 内置函数重名

def print(content):
print(content)

此处会照成, 递归调用, 而且没有出口, 照成报错

*** 递归调用的次数可以自己设置, 通过sys库

返回值类型为多个时的处理方式

def damage(skill1, skill2):
return skill1, skill2

方式一:

result = damage(3,4)
使用过: result[0] result[1] 的使用
缺点: 语义不明确, 不容易后期的维护

方式二:

skill_one_damage, skill_two_damage = damage(3, 4)
使用: skill_one_damage skill_two_damage
优点: 语义明确

序列解包

a,b,c = 1,2,3 元组
a,b,c = [1,2,3] 列表

参数

  1. 形式参数

  2. 关键字参数
    def func(a, b)

    调用: func(b=1, a=2)
    好处: 更容易阅读, 传参顺序灵活, 不影响函数的行为和功能

  3. 默认参数

注意: 关键字参数 和 默认参数 不能和普通参数有交叉, 有混杂的使用的

面向对象

类定义

  1. 类事现实世界或思维世界中的实体在计算机中的反应
  2. 它将数据以及这些数据上的操作封装在一起

** 注意点: 行为一定要找到主体, 很多人困惑于这一点
行为 和 主体 的把控非常的重要的

类是事物的一个抽象

类的设计, 是一种艺术, 比较难做到

局部变量不会覆盖全局的变量

c = 50
def add(x, y):
    c = x + y
    print(c)

print(c) #值未改变

理解类变量和实例变量的区别

实例变量: 具体事物的属性
类变量: 抽象事物的属性

什么时候, 用类变量, 为什么要有类变量 值得我们的思考, 实例变量也是如此

类是生活中事物抽象到计算机中的反映, 如何面向对象, 是一个漫长的过程

python中的类变量和实例变量的表示

类变量:     和类相关  而不是  只和对象有关
class Student{
  name = ''   # 相当于Java中的静态变量
  age
}
#实例变量
class Student{
  def __init__(self, name, age){
    self.name = name
    self.age = age
  }
}

值得我们注意的是:
实例化的对象中, 如果类变量和实例变量重名, 类变量将会被隐藏, 但是可以通过类名来调用

查看类 或者 对象中所有属性的方法

对象/类.dict # 内置的变量

类中如何访问类变量

  1. Student.sum1
  2. self.class.sum1

什么时候使用类方法 什么时候 使用静态方法

方法体与类没有任何关联的时候, 使用静态方法
有关联的时候使用 类方法, 因为更符合 面向对象

类方法, 一般操作 类变量 产生行为

  • 注意 : 推荐使用, 类名 调用类方法, 而不是 使用 实例变量调用 类方法, 这个更符合面向对象, 语义更佳明确*

装饰器 初了解

@staticmethod

@classmethod

python中的私有变量 和 私有方法

def __init__():
  self.__name   # 私有变量

def __funcname(): # 私有方法

注意 构造函数 不是私有的方法, funcname 都不属于 私有

python中没有绝对意义上的私有变量(包括 实例变量和 类变量) 和 私有方法

为什么?
本质: 还是因为pyton是动态语言, 无法阻止动态的读取
"私有"原理: 其实是隐藏, 私有变量 改了别名
例如 私有变量 self.__name 会被pyton解析成 _ClassName__name , 重新改了 命名
还是可以通过, 实例对象._ClassName_name 来访问和修改

如何查看?
通过: student.dict 打印字典, 来查看
强制修改: student._Student__name = ‘’

但是, 我们还是要准寻, 默认其是私有的, 不破坏规则

python 中的继承, 构造方法, 使用父类的特点

使用方法一:(不推荐)

class Student(Human):
      def __init__(self, school, name, age):
        Human.__init__(self, name, age)

缺点: 如果继承的类改变了, 那么构造方法 也需要做改变

方法二:

class Student(Human):
      def __init__(self, school, name, age):
        super(Student, self).__init__(name, age)

解决以上的缺点

如何使用 父类 中的其他方法

class Student(Human):
      def home_work(self):
          super(Student, self).home_work()

正则表达式

a.index(‘python’) > -1

‘python’ in a

最常用的正则表达式
导包: import re
re.findall(‘rule’, str)

常用正则

\d 数字
\w 数字 和 字母 单词字符 还有 下划线 也可以匹配

注意: 只能匹配单一的字符

字符集匹配

a[abc]c # 匹配, abc, aac …
a[a-c]]c 等价

概括字符集

\d 等价于 [0-9]
\w 概括了 [a-zA-Z0-9_]
\s 概括了 \n \t \r space 空白字符

数量词

用武之地: 重复需要多次匹配同一个规则
[a-z]]{3,6} 匹配 3到6个

贪婪与非贪婪

[a-z]]{3,6}
贪婪的, 最大限度的连续匹配

[a-z]]{3,6}? 具体 {3,6}?
非贪婪的

举例
python? 这里的问号 不是非贪婪的表示, 而是 默认的贪婪模式 ? 表示匹配 0 或者 1次

如何改成非贪婪 —> python{0,1}? 此时为非贪婪

*匹配0次, 或者无限多次

  • 零次或者无限多次
  • 一次或者无限多次
    ? 零次或者一次

边界匹配

^ 以什么为开头 从前往后匹配
& 以什么为结尾 从后往前面匹配
^ $ 完全匹配, 一字不漏

匹配模式

. 匹配所以字符 除了 \n
那么怎么让 . 匹配所有的字符, 包括 \n
re.S 模式 , 让 . 匹配所有字符
re.findall(‘正则表达式’, content, re.S)
re.I 不区分大小写匹配

re.sub 替换匹配项 的用法(函数)

re.sub('parttern', 函数或者 字符串, count, flag)

# 函数的形式:
def convert(value):
    macth = value.group()
    return "!!" + macth + "!!"  # 返回值, 就是替换值

count 匹配 几次 符合的  count = 0 全部匹配
flag 模式   re.I | re.S

search 和 match 的区别

search(parttern ,string) 从头到尾, 找到第一个停止
match 从头开始匹配, 首位置没有匹配到到, 就停止

分组 () 的高级使用

import re
s = 'life is short, i use python'
result = re.findall('((life)(.*)(python))', s)
result1 = re.search('(life(.*)python)', s)
print(result)
print(result1.group(1))

结果
[(‘life is short, i use python’, ‘life’, ’ is short, i use ', ‘python’)]

life is short, i use python
结果我们可以看出来, [] 列表的长度是匹配到的 最大分组的个数
() 元组的长度, 是大分组下的 所有小分组 匹配到的 的字符

group() 与 groups() 的使用

  • group(num) num = 0 —> return 完全匹配
    1 —> return 第一个分组
    2 —> return 第二个分组
  • group(num1, num2, num3 …) return 指定的分组, 元组的形式返回
  • groups() return 所有的分组

什么情况下使用正则 什么情况下 使用内置函数

使用正则:
1. 以学习为目的

使用内置函数:
1. 提高开发的效率

JSON (JavaScript Object Notion) JS 对象标记语言

JSON 的本质

是一种轻量级数据

!! JSON指一种数据格式

字符串是 JSON 的

JSON 字符串: 符合JSON格式的字符串

JSON 优点

  • 易于阅读
  • 易于解析
  • 网络传输效率高
  • 跨语言交换数据

对于JSON的 见解

JSON 以一种与 语言无关的语言, 因此 它的 格式不管在什么语言中表示, 都是相同的格式, 每种语言中都会有相应的JSON语言的映射
JSON | python

Array | list
object | dict
number | int/float
null | None
true/false |True/False
string | str

还会有其他语言的相应的映射

相对于用户来讲: 其实, 每一种语言都是很多种语言的语法糖, 都是类似的
相对于系统来讲: 底层的机制还是有很多不一样的地方的, 比如内存的管理, 垃圾回收

序列化 与 反序列化

序列化: 将某种语言, 转换成JSON对象 json_object = json.dump(json_str)
json_str = json.

JSON对象. JSON. JSON字符串 ???

JSON 是一种独立的语言存在, 并不是在javasript中独有的, 只是遵循了ECMASCRIPT 的标准, JSON 也是遵循了 这个标准, JSON 也是遵循了这个标准, 所以数据类型是一样的, 但是本质上 不能认为是同一个东西

JSON 存在的意义

就相当于: unicode存在的意义是一样的, 它作为 其他各种类型语言的一种中间交换的数据格式, 如果没有的json这种中间数据交换格式, 一个语言要和另外一个语言互通, 就要学习对方的语言, 如果语言特别多的化, 就要学习更多的语言

枚举类型

枚举的替代品

{‘YELLOW’:1, ‘GREEN’:2} # 字典替代

缺点: 值可以修改

class Com():
   yellow = 1
   green = 2
   green = 2

缺点: 值可以修改, 并且, 标签可以相同,不会报错

正确的使用枚举

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3
    PINK = 4

print(VIP.BLACK)

advantage: the value is not be change, and the lable is not common

获取枚举类型的值 或者 标签

value VIP.GREEN.value
label VIP.GREEN.name
type VIP[‘GREEN’] == VIP.GREEN

枚举类型的遍历

for v in VIP:
print(v)

枚举的比较 和 判断 是否是同一个枚举

VIP.GREEN == VIP.GREEN
VIP.GREEN is VIP.GREEN

但是不能进行大小的比较

枚举常见的错误和误区

枚举标签相同值得情况:

class VIP(Enum):
    YELLOW = 1
    GREEN = 1
    BLACK = 3
    PINK = 4

print(VIP.GREEN)

for v in VIP:
  print(v)  

输出的结果 —> VIP.YELLOW 不是 VIP.GREEN
此时的 GREEN 相当于别名

遍历不会出现 VIP.GREEN

class VIP(Enum):
    YELLOW = 1
    GREEN = 1
    BLACK = 3
    PINK = 4

for v in VIP.__menbers__:
  print(v)  

这种可以打印出所有的标签, 但是没有值

class VIP(Enum):
    YELLOW = 1
    GREEN = 1
    BLACK = 3
    PINK = 4

for v in VIP.__menbers__.items():
  print(v)  

这种可以打印出 标签和值, 但是结果看起来比较复杂

如何将数值类型转换成枚举类型

print(VIP(1)) ----> 将会输出 VIP.YELLOW

应用: 将枚举类型存到的数据库的时候, 是存的数字, 节约数据库的空间,
提取出来的时候, 应该怎么将数据库中的 数值 变为对应的枚举类型

如何避免枚举类型 标签 值相同的问题 或者说 类型相同的问题

from enum import IntEnum,unique

@unique
class VIP(IntEnum):
    YELLOW = 1
    GREEN = 1
    BLACK = 3
    PINK = 4

for v in VIP.__members__.items():
  print(v)  

是否需要学习 设计模式( 对于设计模式的见解 )

设计模式用来干嘛的
用来应变长期的项目变化的, 使得代码容易维护

是否该用设计模式:

1. 成本估计. 设计模式的使用, 在项目的初期是需要花费大量的精力的, 如果是一个生命周期比较短的项目,不建议使用设计模式, 因为不值得, 如果 **是一个平台** 那么它的生命周期将会很长, 那么它将使用于使用, 设计模式

2. 你所处于的环境. 如果你的team都不懂设计模式, 那么你纠结设计模式, 使用设计模式, 反而会引起反作用, 你团队的其他成员, 看不懂你的代码, 而且, 代码写的比较糟糕, 就算你开始花了很多时间将其设计完毕, 并且使用了, 但是经过, 其他人维护几次就成坏了, 而且可能维护成, 你看不懂, 别人也看不懂. 如果你的团队成员, 都追求代码的美丽, 都会使用设计模式, 那么设计模式, 将发挥他的作用, 和优势

所以说, 初级的程序员, 不用太纠结于设计模式, 因为基本用不上, 而且没有代码的经验作为支撑, 也不足以你能够好好理解他, 能将其发挥出来, 一般工作了好几年之后, 业务逻辑都写烂了, 开始追求代码的美丽了

python 一切皆对象

变量是对象
函数是对象 其他语言中, 函数只是一个代码, 需要一个入口来调用
字符串是对象

所以 函数名 可以当作参数 也可以当作返回值

函数式编程

闭包函数

闭包: 保存一个环境, 保护现场是一样的道理

闭包的现象: 函数 + 定义时的环境

def a():
  c = 2
  def b(x):
    return c * x
  return b
fuc = a()
print(fuc(2))

fuc() 函数中的 c 值, 取决于 当时环境中的 c 也就是 c = 2

闭包这个词非常的形象, 暴露在外, 就不是闭包

c = 4
def a():
  def b(x):
    return c * x
  return b
fuc = a()
print(fuc(2))

此时 b 使用的 c 是 c = 4的值

注意如果函数没有使用外部的东西, 那么将不会是闭包的函数.

不是闭包的情况

c = 4
def a():
  def b(x):
    return x
  return b
fuc = a()
print(fuc(2))

查看函数是否是闭包函数
print(fuc.closure)

闭包到底有什么用, 在什么时候用

正确认识闭包: 不用闭包, 也可以面向对象, 功能也可以照样实现, 并不是一定要掌握闭包

没有闭包的场合, 可以用global来解决问题

场景: 一个人, 每次走3步, 每次打印出走到的位置, 初始的位置为 0

global 来解决问题

steps = 0
def person():
  def walk():
    global steps
    steps += 3
    return steps
  return walk
walk = person()
print(walk())
print(walk())
print(walk())

闭包 来解决问题

def person():
  steps = 0
  def walk():
    nonlocal steps
    steps += 3
    return steps
  return walk
walk = person()
print(walk())
print(walk())
print(walk())

安全性的思考

虽然说, 全局变量可以代替闭包函数的作用, 但是 全局变量使用的过多不安全, 而闭包 使用的不是全局变量, 也能够实现, 需要全局变量才能实现的功能

所以说使用场合: 闭包和全局都能实现的时候, 优先使用闭包

函数式编程的思考

闭包只是函数式编程的应用, 并等于函数式编程

函数式编程只是一种思维

闭包的缺点: 由于保存了太多的现场, 可能会造成内存的泄露, 用的过度反而会造成问题, 但是, 也不能否定它的好处, 和存在的意义

闭包的用于不用, 取决于习惯, 有些人习惯面向对象来编写, 也行, 没有说哪种方式的好与不好

匿名函数

lambda表达式 后面只能是 表达式, 不能有 while for 等等, 复杂的语句

lambda x,y: x+y

python 的三元表达式 ( 使用lambda合适)

True 返回 结果 if 雕件判断 else False 返回的结果

r = x if x > y else y

map的使用 (配合 lambda 来使用, 循环处理数据)

基本使用:

l = [1,2,3,4,5]
r = map(lambda x: x*x, l)
print(list(r))

多个list, 多参数

l = [1,2,3,4,5]
s = [1,2,3,4,5,6,7,8]
r = map(lambda x, y: x*y, l, s)
print(list(r))

结果 [1, 4, 9, 16, 25]

注意: 返回的结果的长度, 取决于, 短的一个列表的长度

reduce 的使用 ( 连续计算 )

场景: 一个人按照 path 中的路径走, 最后走到哪个点

from functools import reduce # 导包

path = ((1,2), (3,-1), (7, 8), (-11, 2))

coordinate_end = reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), path, (0,0))

print(coordinate_end)

结果 (0 ,11)

参数 1: function
参数 2: 列表 或者 元组 ,可以遍历的就行
参数 3: x 的初始值

filter 的用法 (过滤器, 判断是否时英文句子的开头, 过滤大小写)

l = [1,2,3,4,5,6,7,8]
r = filter(lambda x: True if (x%2 == 0) else False, l)
print(tuple(r))

(2,4,6,8)

函数式编程与命令式编程的区别

命令式编程 是我们从小到大习惯的编程方式
def
for
if else
几乎可以让我们编写所有的逻辑

函数式编程 不是很多人能多接受的方式, 但是在人工智能中, 还是有用到的, lisp 语言

不能说python是, 函数式编程的语言, 只能说它是支持的, 就是让你体验体验, 简化代码, 但不推荐, 所有逻辑都用函数式编程来写, 第一, 易读性不是很好, 其他没接触过的人, 或者接触很少的人, 可能会觉得比较吃力

装饰器

装饰器 只是一种模式
是一种语法糖, 简化代码的语法糖

def haha(func):
  def wrapper():
    print("It is new function")
    func()
  return wrapper

@haha
def f():
  print('I am oringin func')

f()

优点:

  • 简化了函数的调用流程
  • 符合开闭原则
  • 易读性

适用的场景

  • 需要扩展函数的新功能, 且需要符合开闭原则

注意 如果和特定的函数绑定在一起, 没有任何的意义

思考

演变的, 为什么出现, 有什么用, 怎么用, 这样来理解和讲课的方式, 比较好

就像, 一个产品的升级, 都是从问题, 和痛点出发, 去寻找解决办法, 由此产生了下一个产品, 如果是学习为目的, 新产品的由来, 的了解是很重要的

装饰器 通用形式 加了 *args

def haha(func):
  def wrapper(*args):
    print("It is new function")
    func(*args)
  return wrapper

@haha
def f(x, y):
  print('I am oringin func', x, y)

@haha
def f1():
  print('I am oringin func')

f(5, 6)
f1()

*args 通配参数
不管函数有没有参数, 有几个参数, 都可以装饰

装饰器 全通配函数形式, 增加 **kw


def haha(func):
  def wrapper(*args, **kw):
    print("It is new function")
    func(*args, **kw)
  return wrapper

@haha
def f(x, y):
  print('I am oringin func', x, y)

@haha
def f1():
  print('I am oringin func')

@haha
def f2(x, y, z, **kw):
  print('I am oringin func', x, y, kw)

f(5, 6)
f1()
f2(1,2,3, a =1,e=3,c= 4,b =6)

It is new function
I am oringin func 5 6
It is new function
I am oringin func
It is new function
I am oringin func 1 2 {‘a’: 1, ‘e’: 3, ‘c’: 4, ‘b’: 6}

关键字参数

*args 代表, 普通的形参 (1,2)
**kw 代表, 关键字形参 (a=1,b=2)

网络爬虫

爬取一个直播网站, 并且按照人气, 显示主播的排名和粉丝数

用到的方法

sorted(iterator, key=一个有返回值函数,排序就是按照, 返回值, reverse=True降序)

re.findall()    正则的使用

request.urlopen().read()  返回  二进制码

str(二进制码, encoding)
from urllib import request
import re


class Spider:
    url = "https://www.huya.com/g/wzry"
    # parttern = 'class="txt">[\s\S]*?([\s\S]*?)<[\s\S]*?[\s]*    '
    parttern = '[\s\S]*?[\s]*'

    def __fectch_html(self):
        r = request.urlopen( Spider.url )
        html = r.read()
        html = str( html, 'utf-8' )
        return html

    def __analysis_html(self, html):
        r = re.findall(Spider.parttern, html)
        # r = re.findall('title="([\s\S]*?)">[\s\S]*class="js-num">([\s\S]*)', str(r))
        r = re.findall('title="([\s\S]*?)"[\s\S]*?js-num">([\s\S]*?)[\s]*, str(r))
        # result = re.findall( Spider.parttern, html)
        anchors = []
        for u in r:
            name = u[0]
            num = u[1]
            anchor = {'name': name, 'number': num}
            anchors.append(anchor)
        return anchors

    def __sort(self, anchors):
        r = sorted(anchors, key=lambda anchor: float(re.findall('[\d\.]*',anchor['number'])[0])*10000 if '万' in anchor['number'] else float(anchor['number']), reverse=True)
        return r

    def __display(self, anchors):
        for rank in range(1, len(anchors) + 1):
            print( '第->', rank, '<-名-------', anchors[rank-1]['name'], '----------', anchors[rank-1]['number'] )

    def go(self):
        html = self.__fectch_html()
        r = self.__analysis_html( html )
        r = self.__sort(r)
        self.__display(r)

sp = Spider()
sp.go()

python 杂记

用 dict 代替 switch

import random
day = random.randint(0,7)

def get_monday():
  return 'Monday'

def get_tuesday():
  return 'Tuesday'

def get_wendesday():
  return 'Wendesday'

def default():
  return 'NoDefine'
switch = {
  1:get_monday,
  2:get_tuesday,
  3:get_wendesday
}

day = switch.get(day, default)()
print(day)

推导式 (列表, 集合, 字典))

集合 列表推导式


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

a = {v**2 for v in a}   # 结果取决于 包裹表达式 是什么类型
print(a)

a = [v**2 for v in a if v>5]
print(a)

{1, 4, 36, 9, 16, 25}
[1296, 81, 256, 625]

字典推导式

a = {
  '刘庆柱': 34,
  '阿斯蒂芬': 22,
  'Like': 31
}

# k 与 v 对调
b = { v:k for k,v in a.items() }
print(b)

# 将Key, 转成列表,
c = [ k for k,v in a.items() ]
print(c)

{34: ‘刘庆柱’, 22: ‘阿斯蒂芬’, 31: ‘Like’}
[‘刘庆柱’, ‘阿斯蒂芬’, ‘Like’]

None 不等于 [] False ‘’

python一切皆对象, 所以说, 每种类型 都有相应的对象类型

None —> NoneType
[] —> List
‘’ —> Str

他们每一个都有自己的意义, 所以说, 他们不能等价


print([] == None)
print({} == None)
print([] == {})
print([] == '')
print([] is None)

print(not [])
print(not None)

结果

False
False
False
False
False

True
True

可以看出不能完全等价, 只能说要特定的场景下, 可以等价

并不是一个创建的对象, bool(Object) 一定是 True


class Test():
  pass

class Test_one():
  def __len__(self):
    return 0    # 只能是数字 和 布尔值 , 其他类型, 报错

class Test_two():
  def __bool__(self):
    return False  # 不能是整形, 只是布尔型

o = Test()
o1 = Test_one()
o2 = Test_two()

# len(o)  将会报错, 因为 类中没有 __len__() 方法

print(bool(o))  
print(bool(o1))
print(bool(o2))
True
False
False

bool() 方法, 实质是调用了对象中的某些方法

如果__bool__() 存在, 就会调用 def bool() , 如果没有定义, 就会调用 len() 方法

len() 方法, 实质是调用了对象中的__len__() 方法

你可能感兴趣的:(python)