类格式示例:
class Student():
name = ''
age = 0
def print_file(self):
print('name:' + self.name)
print('age:' + str(self.age))
注:类中的函数,参数列表中必须有self,并且如果想在函数中引用类中变量需要使用 self.操作符。
类实例化示例:
student = Student()// Student student = new Student();
没有java里的new 一个实例
运行这个类和调用这个类都要在类的外部
1、面向对象的两个主要部分:类、对象
2、在类的内部:可以定义若干个变量
可以定义函数
3、调用类:将类实例化 用一个变量来接收实例化的结果
4、在类里面编写函数的时候一定要传入self
5、在类中函数的定义中用到类中定义的变量时,要用self引入
总结:1、类最基本的理解:对一系列变量和函数进行封装
2、类下面的函数一定要加self,在函数内部要调用类内变量的话要通过self调用
3、类只负责定义,不负责执行,所以在类内不能对方法进行调用
构造函数
①实例化过程自动调用构造函数,
可以在构造函数里初始化对象的特征
构造函数可以让类生成不同的对象,实例化传入不同的参数
python中构造函数的格式:
def __init__(self,name,age):
self.name=name
self.age=age// this.age = age;
注:python中的构造函数可以显示调用,但很少这样做。如:
student1 = Student('石敢当',18) #构造函数在实例化的时候自动调用
student1.__init__()
此时用这种显示方式调用构造函数与调用普通函数无异,并且这样调用也只返回None.
②不能强制返回其他类型
类变量就是和类相关联的变量;
实例变量是和对象相关联的变量,在构造函数里通过self.变量名 来保存实例变量
class Student():
#此处定义的是类变量
sum = 0
def __init__(self, name, age):
#此处定义的是实例变量
self.name = name
self.age = age
方法
实例方法,定义时必须写上self,调用时不需要
1、也可以换成this,但是建议写self
2、代表是实例而不是类
3、self必须写
4、实例方法,实例可以调用的方法
5、self可以换为别的this之类的,所以不能称之为关键字
类方法格式:
加了这个@classmethod 就是一个类方法 不加就是实例方法
注:这里的cls表示class类,也可以使用别的名字表示,但是建议使用cls这个名字作为参数。
此外,类方法中操作类变量,直接使用‘cls.类变量’即可。而且python里对象也可以调用类方法。
静态方法
@staticmethod
def add(x,y):
pass
静态方法不同于类方法、实例方法,没有默认强制传入参数(self,cls)
与类方法类似,静态方法需要在方法前写入@staticmethod装饰器
静态方法也可以被对象或类调用,且静态方法的内部也可以访问类变量
静态方法或类方法中调用实例变量会报错,无法执行
静态方法可以用,但是一个独立的方法,与类和实例关联不大
成员的可见性()
Python中没有public和private这样的标识符来确定方法和变量的可见性
Py中是在方法名前加上双下划綫就可以确定这是个private的
为了保证数据的安全 把成员变量修改的这种功能写在方法内部
为了保证数据的安全 把成员变量修改的这种功能写在方法内部
比如这里的修改score的这个方法,没有选择初始化这个变量,而是把赋值的这个部分放到了方法体中,保证了数据安全性和一系列的逻辑操作有地方可以放了
在py中没有什么是绝对的不能访问
Python的动态特性会导致给对象之前不存在的属性赋值时自动创建该属性。而当该属性名为__开头且不以__结尾(例如__score)时:
1. 当此赋值操作发生在类的实例方法中时,实际保存在__dict__中的是:_类名__score。访问此属性,在类中可以直接通过 __score 或 _类名__score访问。在类外只能通过_类名__score访问。
2. 当此赋值操作发生在类的外部时,实际保存在__dict__中的是:__score。如果之前定义过一个”私有属性“__score,由于实际上在__dict__中的key不一样,他们将是两个不同的属性。
面向对象的3大特性:
1.继承性
2.封装性
3.多态性
python中的继承:
写法:
from 模块 import Human
class Student(Human):
pass
子类可以继承父类的一切
子类调用父类的构造函数:
可以直接调用父类的构造函数,但必须传递self参数
def __init__(self,school,name,age):
self.school = school
Human .__init__(self,name,age)
Java中只能支持单继承 但是py中可以支持多继承
子类方法调用父类方法: super关键字
python中super关键字用法与java不同,它主要是用来在子类中调用父类方法,如在子类构造函数中调用父类构造函数:
def __init__(self, name, age):
super(子类名, self).__init__(name, age)
也可以调用父类普通方法。
当子类的方法和父类的方法同名时,Python会优先调用子类的方法 需要用super关键字去调用父类方法
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
正则表达式
Import re #re是py官方给的库,里面有很多方法去操作参数
1. 正则表达式, 为原生爬虫做准备
正则表达式是一个特殊的字符序列, 一个字符串是否与我们所设定的字符序列相匹配。
快速检索文本,实现一些替换文本的操作。
应用场景:
1) 检查一串数字是否是电话号码
2)检查一个字符串是否email
3 ) 把一个文本里指定单词替换。
2. JSON(XML), JSON 是一种轻量级的数据格式。是Web数据交换的主流数据结构。XML用得比较少了。正则表达式的核心思想精髓是规则。
# 正则表达式里,像'Python', 称为 普通字符,而像 '\d' 则称为元字符。 普通字符可以和元字符混和搭配来作为正则表达式的匹配规则或需求。
# 我们学习正则表达式就是学习元字符,‘\d’是众多元字符里的其中一个
# re.findall('', 字符串), 结果返回的是一个列表。
编码是先根据业务需求分析,然后到正则表达式列表里查找涉及的单个元字符,然后再把这些单个元字符组合成能解决问题的正则表达式。
字符集的使用(可以配合正则表达式使用)
该正则表达式可以找到acc和afc从s里
字符集:
[cf]:匹配c或者f
a[cf]c:使用a和c定界限,匹配c或者f
a[c-f]c:若需匹配的字母较多,可使用c-f的这种方式匹配,即可匹配到c到f中的所有字母
a[^cf]c:匹配字符集中不含c或f字母字符串
衍生:
[a-z]:可匹配所有字母
[^a-z]:可匹配所有非字母
常见的概括字符集:
\d:0-9的数字,等价于[0-9]
\D: 非数字,等价于[^0-9]
\w:匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
\W:匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\s:匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
\S:匹配任何可见字符。等价于[^ \f\n\r\t\v]
.匹配除换行符\n之外的其他所有字符
字符集和概括字符集都只能匹配单一的字符
数量词:
如果索要筛选的字符集是重复的,可以用数量词进行指代,如[a-z]{3};
数量词也是支持区间范围的,{3,6},即同时匹配3个字母,或者匹配4个字母,或者匹配5个字母,或者匹配6个字母,这个机制体现了一个非常重要的机制,即是否贪婪;
Py中是默认的贪婪的
a='python 111java678php'
r=re.fingall('[a-z]'{3},a)
print (r)
[a-z]--->'p','y','t','h',......,'p','h','p'
[a-z]{3}--->'pyt','hon','jav','php'
贪婪与非贪婪
贪婪:
[a-z]{3,6}--->'python','java','php'
非贪婪:
[a-z]{3,6}?--->'pyt','hon','jav','php'
这个*代表着匹配多次和匹配0次
所以输出的就有pytho python pythonn
10-7
1.*匹配0次或者无限多次,输出的结果是['pytho', 'python', 'pythonn']
2.+匹配1次或者无限多次,输出结果是['python', 'pythonn']
3.?匹配0次或者1次,输出的结果是['pytho', 'python', 'pythonn']
例子:
import re
a='pytho0python1pythonn2'
r=re.findall('python?',a)
print(r)
输出结果为['pytho', 'python', 'python']
边界匹配符
^开始边界
$结束边界
[0-9] 中的[-]代表的范围
{,}区间
qq='1000110001'
r=re.findall('^\d{4,20}$',qq)
print(r)
qq='1000110001'
r=re.findall('^[0-9]{4,20}$',qq)
print(r)
组的定义
import re
a = "PythonPythonPythonPythonPython"
r = re.findall("(Python){3}",a) #表示Python以组的形式匹配 连续出现3次才算匹配成功
print(r)
PS : [abc] a或b或c (abc)且关系 要求abc连续出现
把Python用括号包起来
sub查找并替换(简单的字符串替换可以用字符串内置函数,如str.replace)
注:使用sub进行正则替换时可以传入函数来进行替换,如:
import re
s = 'pythonC#GOjavaphpjsC#'
def convert(value):
matched = value.group() #sub函数中c#被当做参数传到了函数convert中
return '!!'+ matched + '!!' #且value是一个对象
r = re.sub('c#',convert,s,1,re.I)
print(r)
demo 把函数作为参数传递的demo
# 通过/d获取数字
# 通过value.group()这个函数今次获取对象中的数字
# 通过int(matched)将对象转型为字符串,因为正则表达式只能针对字符串
# 通过return '9'将对象转化为字符串
正则表达式中match和search函数
re.match 和 re.search 函数
1、re.match
从开始处开始匹配,如果开始第一位就不匹配,返回None。
2、re.search
从开始处开始搜索,搜索整个字符串,如果匹配,立即返回第一个对象,否则返回None。
与findall的区别:
1、findall返回结果为list match与search返回为对象(如果需要获取对象内容,需要用到group()方法,如果需要返回位置,可以使用span()方法)。
2、match与search只会匹配一次,无论成功与否,都会返回结果。
推荐使用findall
比如:
正则表达式中组group的概念:
用括号括起来的多个字母,用于一次匹配一个字符串而不是单个字符。如果正则表达式中都是普通字符的话,默认是一个组。
在使用re模块中的search函数时,访问返回的匹配字符串时,可以使用group函数指定要访问的组,如:
注:若组号为0表示整个字符串。也可以使用groups函数以字符串元组形式返回所有匹配字符串。
Groups不会返回完整的匹配
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------