【自学用】B站python爬虫课程笔记(Q11-15)
下面是学习的网址:
【Python+爬虫】
11、class定义类别的一些问题
我写的"可爱小猫类别"的代码如下:
class CuteCat:
def __init__(self, cat_name, cat_age, cat_color, cat_temper):
# cat_name = name
# self_name = cat_name # 这两种定义方式都是错的
self.name = cat_name # 定义方法的时候用的是“对象.方法”,中间是英文句号而不是下划线
self.age = cat_age
self.color = cat_color
self.temper = cat_temper
# 两个不同的函数定义之间起码要有一行空行,这是python的编码规范,不然在pyCharm会划波浪线警告,下方第9行和第13行是空行
def speak(self):
print("喵"*self.age) # 可以直接重复打印,字符*次数。为什么到这里self.age就可以直接用了?前面定义过,而且是在同一个class类别里面
def think(self, content):
print(f"小猫{self.name}在思考{content}")
cat1 = CuteCat("Jojo", 3, "橙色", "温顺")
cat2 = CuteCat("Dior", 2, "黑色", "比较暴躁")
print(f"这只小猫叫{cat1.name},今年{cat1.age}岁了,它是{cat1.color}的,性情{cat1.temper}") # 花括号里应该填cat1.方法
cat1.speak()
print(f"另外这只小猫叫{cat2.name},今年{cat2.age}岁了,它是{cat2.color}的,性情{cat1.temper}")
cat2.think("你瞅啥?")
从上至下会有如下的问题
1)定义init初始化函数的一些问题
- 定义初始化函数的英文缩写是initialize的缩写init,我第一次就打成了整型的缩写int;
- init前后是两个短的下划线;
- 必须最先开始定义有初始化函数,没有这个函数接下来的self不能用就会报错;下面是我尝试不用init初始化函数看还可不可以定义类别的代码,后面运行发现是不行的。
# 会报错
class CuteCat:
def speak(self):
print("喵"*3) # 可以直接重复打印,字符*次数。为什么到这里self.age就可以直接用了?前面定义过,而且是在同一个class类别里面
def think(self, content):
print(f"小猫在思考{content}")
cat = CuteCat
cat.speak()
cat.think("你瞅啥?")
- init初始化函数里面的内容也是" self.方法 "开头,我错误地写成了self_方法,cat.方法,cat_方法
2)定义两个不同函数之间要有空行
两个不同的函数定义之间起码要有一行空行,这是python的编码规范,不然在pyCharm会划波浪线警告,可爱小猫第9行和第13行是空行
PEP 8: E301 expected 1 blank line, found 0 # 警告信息
前面应该(expeted)有1个的空行(black line),但是发现0行
3)print的技巧
print可以直接重复打印,字符串*次数
12、class定义类别的一些问题2
打印"学生成绩"的例子,下面两个代码其实是一样的,但遵循DRY原则,第二个代码明显更好:
class Student:
def __init__(self, student_name, student_id, student_grades): # 可以不用student_grades
self.student_name = student_name # self.后面可以不用那么长,用self.name也行
self.student_id = student_id
self.student_grades = {"语文": 0, "数学": 0, "英语": 0} # 定义了在类别里面也不一定要用
def set_grade(self, course, grade):
if course in self.student_grades:
self.student_grades[course] = grade
wang = Student("小王", "10086", {"语文": 0, "数学": 0, "英语": 0})
zhang = Student("小张", "10000", {"语文": 0, "数学": 0, "英语": 0})
wang.set_grade("数学", 90) # 只改变数学科目的成绩,其他都是0分
print(f"{wang.student_name}({wang.student_id})的成绩为:{wang.student_grades}")
class Student:
def __init__(self, student_name, student_id):
self.name = student_name # self.后面可以不用那么长,用self.name也行
self.id = student_id
self.grades = {"语文": 0, "数学": 0, "英语": 0} # 定义了在类别里面也不一定要用
def set_grade(self, course, grade):
if course in self.grades:
self.grades[course] = grade
wang = Student("小王", "10086") # 这样这里面就不用重复输入初始的三门成绩了
zhang = Student("小张", "10000")
wang.set_grade("数学", 90) # 只改变数学科目的成绩,其他都是0分
print(f"{wang.name}({wang.id})的成绩为:{wang.grades}")
最后的这组for循环打印字典里面键值对学科-成绩的综合运用还没有学会,权当做练习了。
class Student:
def __init__(self, student_name, student_id):
self.name = student_name # self.后面可以不用那么长,用self.name也行
self.id = student_id
self.grades = {"语文": 0, "数学": 0, "英语": 0} # 定义了在类别里面也不一定要用
def set_grade(self, course, grade):
if course in self.grades:
self.grades[course] = grade
def print_grades(self):
print(f"{self.name}同学({self.id})的学习成绩为:")
for course in self.grades:
print(f"{course}: {self.grades[course]}") # course和self.grades[course]都要用花括号括起来
wang = Student("小王", "10086") # 这样这里面就不用重复输入初始的三门成绩了
wang.set_grade("数学", 90)
wang.set_grade("语文", 95)
wang.set_grade("英语", 92)
wang.print_grades() # 结尾要有小括号结束
13、class_inheritance类别继承的一些问题
"动物--人类--小猫--小狗"父子类分类的代码如下:
class Animal:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
self.num_eyes = 2
def breathe(self):
print(self.name + "在呼吸")
def poop(self):
print(self.name + "在拉屎")
class Human(Animal):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.has_tail = False
def read(self):
print(f"{self.name}在阅读")
class Cat(Animal):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.has_tail = True
def scratch_sofa(self):
print(f"{self.name}在抓沙发")
class Dog(Animal):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.has_tail = True
def play_ball(self):
print(f"{self.name}在玩球")
cat1 = Cat("Jojo", 2, "boy")
print(cat1.has_tail)
print(cat1.num_eyes) # 可以直接调用初始化函数的数据int整型2
# print("cat1.has_tail") # 对象的函数不能用双引号包起来
print(f"这只小猫的名字叫做{cat1.name},今年{cat1.age}岁了,是一个{cat1.sex}!")
print(f"{cat1.age}")
print(cat1.age) # 第二种更加简单
cat1.scratch_sofa()
cat1.breathe()
# print(f"{cat1.scratch_sofa()}") # 为什么打印出来下一行是None?因为多用了一个print,本身scratch_sofa函数就是定义的打印了
# print(f"{cat1.breathe()}")
print("它有尾巴吗?" + str(cat1.has_tail))
print(f"它有尾巴吗?{cat1.has_tail}")
print(cat1.has_tail) # 三行都一样的,返回True布尔值
1)定义两个不同类别之间要有两行空行
2)父类子类里面定义的函数可以直接用
print("它有尾巴吗?" + str(cat1.has_tail))
print(f"它有尾巴吗?{cat1.has_tail}")
print(cat1.has_tail) # 三行都一样的,返回True布尔值
直接用的方法是 “对象 . 函数” ,也可以不用print,只不过有的函数你运行之后看不到运行结果,
3)定义函数为打印,再打印这个函数,则会多出一行为None,没有返回值
print(f"{cat1.scratch_sofa()}") # 为什么打印出来下一行是None?因为多用了一个print,本身scratch_sofa函数就是定义的打印了
cat1.scratch_sofa() # 函数可以直接用,且这个函数定义就是打印,所以可以运行显示
第一行运行结果下面还有一行None,就是因为重复打印返回默认空值的结果。第二行就没有事。
14、open-file-read打开文件读取的一些问题
1)Windows的文件绝对地址
比如我在桌面建立了一个txt文件,可以右键这个文件图标, 复制文件地址,得到的地址是:
"C:\Users\ABC\Desktop\test.txt"
而你输入到open函数里面会报错,因为你要将单反斜杠变成双反斜杠:
"C:\\Users\\ABC\\Desktop\\test.txt"
这样子你就能根据路径打开对应位置的文件了。
2) 打印两行readline之间会有一行空行
这个UP主在视频中已经说得很清楚了,主要是readline会读取文件中每一行末尾的换行符,print函数结尾默认换行,所以会打印出一行空行。
3)with关键字而不用close()
用下面这段代码:
with open("C:\\Users\\ABC\\Desktop\\test.txt", "r", encoding="utf-8") as f:
而不用这个:
f.close()
可以避免每一次open打开文件结束时要手动输入这么一行close文件,只要开头改了就行。需要注意的是用这个开头下面的语句都要进行缩进,不然跳出了这个范围就不能打开对应文件进行打印输出了。
15、open-file-read&write打开文件读写的一些问题
1)一些知识点
- read读模式下(“r”)如果没有识别到路径当中的文件会报错,而write写模式(“w”)和append附加模式(“a”)下没有文件会自动创建文件名的文件;
- write写模式下(“w”)之前的文件里面有内容会被write写下来的内容覆盖掉,而append附加模式下(“a”)会在之前的基础上再添加;
- 换行符也不一定要在一句话结尾用,也可以在下一行的开头用,效果是一样的;
- 同一文件夹下创建新的文件,macOS的开头是“ ./ ”,Windows是“ .\ ”。
2)r+模式
- 和read读模式(“r”)一样,“r+”模式下路径中的文件必须要已经存在,不然会报错;
- ''r+"模式下既可以读又可以写,但是无法在之前的基础上进行增加,要额外打开append附加模式(“a”) 进行增加;
- 如果之前的文件里面是空的,即使你在''r+"模式的语句里面先写下write内容,再打印下read的内容,输出结果还是空值/或者是空行。按道理老说应该是有东西写进文件里,再读应该有输出才对,但是没有。
with open("./poem.txt", "r+", encoding="utf-8") as f:
f.write("窗前明月光,\n疑似地上霜。\n举头望明月,\n低头思故乡。")
print(f.readline())
# f.write("\n窗前明月光,\n疑似地上霜。\n举头望明月,\n低头思故乡。")
with open("./poem.txt", "a", encoding="utf-8") as f:
f.write("\n唐 李白")