Python面向对象

类的定义 把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念 对象的定义 基于类而创建一个具体的事物,类的实例化 接口继承 继承的第二种含义非常重要。它又叫“接口继承”。 接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 导入抽象基类模块 import abc # 定义接口(基类) class File(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass class disk(File): def read(self): print("disk read") def write(self): print("disk wirte") ds = disk() ds.read() 子类中调用父类的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Grandfather(object): def __init__(self, name, age): self.age = age self.name = name def grandfather(self): print("grandfather method") class Father(Grandfather): def __init__(self, name, age): super().__init__(name,age) def father_method(self): print("father method") class Son(Father): def __init__(self, name, age,sex): # 调用父类的构造方法 super().__init__(name,age) self.sex = sex # 子类中调用父类方法 def son_method(self): Father.father_method(self) def son_method1(self): super().grandfather() son1 = Son('xiaoming',18, 'male') son1.son_method1() 组合 1、组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。 2、作用是可以将两个本来不相关的类联系起来。一般是两个类之间有显著的不同,很多时候还要附属关系(有相同的属性也有不同的属性)。比如人和头,手机和电池等等。 3、无纵向关系时用组合,有纵向关系时用继承。 4、组合就是一个类中使用到另一个类,从而把几个类拼到一起。组合的功能也是为了减少重复代码 多态 由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同 多态的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体类。 多态表明了动态(又名,运行时)绑定的存在,允计重载及运行时类型确定和验证。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class People(object): def __init__(self, name, age): self.name = name self.age = age def generation(self): if self.age < 18: print("[%s]属于未成年人" % self.name) elif 18 < self.age < 30: print("[%s]属于青年人" % self.name) else: print("[%s]属于中老年人" % self.name) class minor(People): pass class young(People): pass class old(People): pass def func(obj): obj.generation() w1 = young('luenci',20) w2 = minor('xiaoming', 16) w3 = old('jack', 50) func(w1) func(w3) func(w3) out: [luenci]属于青年人 [jack]属于中老年人 [jack]属于中老年人 反射 getattr(object, name) 得到属性的值 hasattr(object, name) 说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的 setattr(object, name, value) 这是相对应的getattr()。参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供。例如,setattr(x,“foobar”,123)相当于x.foobar= 123 delattr(object, name) 与setattr()相关的一组函数。参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, 'foobar')=del x.foobar 注:getattr,hasattr,setattr,delattr对模块的修改都在内存中进行,并不会影响文件中真实内容。 ...

5 min · 2385 words · Luenci

socket网络编程实战-斗鱼弹幕获取

asyncore模块 介绍 这个模块为异步socket的服务器客户端通信提供简单的接口。 该模块提供了异步socket服务客户端和服务器的基础架构。 相比python原生的socket api,asyncore具备有很大的优势,asyncore对原生的socket进行封装,提供非常简洁优秀的接口,利用asyncore覆写相关需要处理的接口方法,就可以完成一个socket的网络编程,从而需要处理复杂的socket网络状况以及多线程处理等等。 实现流程 客户端 Socket 开发基本使用 1.定义类继承自asyncore.dispatcher 2.实现类中的回调代码 实现构造函数 调用父类方法 创建 Socket对象 连接服务器 实现handle_connect回调函数 当socket连接服务器成功时回调该函数 实现writable回调函数 描述是否有数据需要被发送到服务器。返回值为True表示可写,False表示不可写,如果不实现默认返回为True,当返回True时,回调函数handle_write将被触发 实现handle_write 回调函数 当有数据需要发送时(writable回调函数返回True时),该函数被触发,通常情况下在该函数中编写send方法发送数据 实现readable回调函数 描述是否有数据从服务端读取。返回True 表示有数据需要读取,False表示没有数据需要被读取,当不实现默认返回为True,当返回True 时,回调函数handle_read将被触发 实现handle_read 回调函数 当有数据需要读取时触发(readable回调函数返回True 时),该函数被触发,通常情况下在该函数中编写recv方法接收数据 实现handle_error回调函数 当程序运行过程发生异常时回调 实现handle_close回调函数 当连接被关闭时触发 3.创建对象并且执行asyncore.loop进入运行循环 timeout表示一次循环所需要的时长 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 import asyncore import sys # 定义类继承自 asyncore.dispather class scoket_client(asyncore.dispatcher): # 实现类中的回调代码 def __init__(self, host, port): # 调用父类的方法 asyncore.dispatcher.__init__(self) # 创建 Scoket 服务器 self.create_socket() # 连接地址 address = (host, port) self.connect(address) pass # 实现handle_connect回调函数 def handle_connect(self): print("连接成功") # 实现writable函数 def writable(self): return False # 实现handle_write回调函数 def handle_write(self): # 内部实现对服务器发送数据代码 # 调用 send 方法发送数据,参数是字节数据 self.send("hello world".encode('utf-8')) # self.send("hello world") # 实现readable回调函数 def readable(self): return True # 实现handle_read回调函数 def handle_read(self): # 主动接收数据 result = self.recv(1024) print(result) # 实现handle_error回调函数 def handle_error(self): # 编写处理错误方法 t, e, trace = sys.exc_info() # 实现handle_close回调函数 def handle_close(self): print("连接关闭") self.close() # 创建对象并且执行asyncore.loop 进入循环 if __name__ == '__main__': client = scoket_client('127.0.0.1', 9000) # 开始启动运行循环 asyncore.loop(timeout=5) ...

5 min · 2351 words · Luenci

SQL性能调优

原文链接:https://blog.csdn.net/u010520146/article/details/81161762 一.创建索引 1.要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引 2.1在经常需要进行检索的字段上创建索引,比如要按照表字段username进行检索,那么就应该在姓名字段上创建索引,如果经常要按照员工部门和员工岗位级别进行检索,那么就应该在员工部门和员工岗位级别这两个字段上创建索引。 2.2创建索引给检索带来的性能提升往往是巨大的,因此在发现检索速度过慢的时候应该首先想到的就是创建索引。 2.3一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。 二.避免在索引上使用计算 在where字句中,如果索引列是计算或者函数的一部分,DBMS的优化器将不会使用索引而使用全表查询,函数 属于计算的一种,同时在in和exists中通常情况下使用EXISTS,因为in不走索引。 效率低: select * from user where salary*22 > 11000 (salary是索引列) ...

6 min · 2849 words · Luenci

Vue.js的基本知识

Vue.js概念 Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App,Vue语法也是可以用于进行手机App开发的,需要借助于Weex) Vue.js 是前端的主流框架之一,和Angularjs、Reactjs一起,并成为前端三大主流框架!· Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发) 框架和库的区别 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。 库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。 后端中的MVC与前端中的MVVM之间的区别 MVC是后端的分层开发概念; MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层,分为了三部分Model,View,VM ,ViewModel ...

14 min · 6761 words · Luenci

windows 配置同时使用 Gitlab、Github、Gitee(码云) 共存的开发环境(转载)

原文链接:https://blog.csdn.net/flowerspring/article/details/104962002 清除 git 的全局设置(针对已安装 git) 新安装 git 跳过。 若之前对 git 设置过全局的 user.name 和 user.email。 类似 (用 git config –global –list 进行查看你是否设置) 1 2 $ git config --global user.name "你的名字" $ git config --global user.email "你的邮箱" 必须删除该设置 1 2 $ git config --global --unset user.name "你的名字" $ git config --global --unset user.email "你的邮箱" 生成新的 SSH keys 1)Gitee 密钥 跳转到keygen目录,git bash here。 先键入第二行命令 第四行 指定 id 文件名称为id_rsa_gitee 第五、六行 设置无密码,直接回车两次。 会在keygen目录下生成文件 id_rsa_gitee 和 id_rsa_gitee.pub。 id_rsa_gitee.pub中存放的是公钥。 把公钥保存到gitee网页密钥中。 1 2 3 4 5 6 7 8 9 10 11 12 honey@honey MINGW64 /d/keygen $ ssh-keygen -t rsa -C [email protected] Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/honey/.ssh/id_rsa): id_rsa_gitee Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in id_rsa_gitee. Your public key has been saved in id_rsa_gitee.pub. The key fingerprint is: ... The key's randomart image is: ... 也可指定文件路径,方便后面操作:~/.ssh/id_rsa.gitlab ssh-keygen -t rsa -f ~/.ssh/id_rsa.gitee -C "[email protected]" 直接回车3下,什么也不要输入,就是默认没有密码。 注意 gitee 和 gitlab 的文件名是不同的。 ...

4 min · 1696 words · Luenci

一些核心模块的介绍

sys模块 模块方法 解释说明 sys.argv 传递到Python脚本的命令行参数列表,第一个元素是程序本身路径 sys.executable 返回Python解释器在当前系统中的绝对路径 sys.exit(arg) 程序中间的退出,arg=0为正常退出 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称,Linux是linux2,Windows是win32 sys.stdout.write(str) 输出的时候把换行符\n去掉 val = sys.stdin.readline()[:-1] 拿到的值去掉\n换行符 sys.version 获取Python解释程序的版本信息 os模块 方法 说明 os.mkdir() 创建目录 os.rmdir() 删除目录 os.rename() 重命名 os.remove() 删除文件 os.getcwd() 获取当前工作路径 os.walk() 遍历目录 os.path.join() 连接目录与文件名 os.path.split() 分割文件名与目录 os.path.abspath() 获取绝对路径 os.path.dirname() 获取路径 os.path.basename() 获取文件名或文件夹名 os.path.splitext() 分离文件名与扩展名 os.path.isfile() 判断给出的路径是否是一个文件 os.path.isdir() 判断给出的路径是否是一个目录 json模块 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。 ...

8 min · 3974 words · Luenci

京东全网爬虫

完整代码见: https://github.com/Lucareful/JingDongSpider 写在前面: 折腾了很久的用python做爬虫项目到现在也该告一段落了,看视频学,遇到bug自己查找,代码思路不对重新写,环境不对自己配置….一路上跌跌撞撞,过程很艰苦,所幸结果为好。 ...

4 min · 1890 words · Luenci

基于Python语言的IP代理池

环境:python3.6 MongoDB flask requests等第三方库 完整代码见: https://github.com/Lucareful/IPProxyPool 代理池概述 什么是代理池 代理池就是有代理IP组成的池子,它可以提供多个稳定可用的代理IP 为什么要实现代理池 我们在做爬虫的时候,最常见的一种反爬虫手段就是:IP反爬;也就是当同一个IP访问这个网站的次数过多,频率过高,就会限制这个IP的访问。就是需要经常换IP; 使用IP代理池是其中一个比较常用的方案 免费代理都是非常不稳定的,有10%是可用就很不错了 一些收费代理稳定性也不好 目的:从一堆不稳定的代理IP中,抽取高可用代理IP,给爬虫使用 代理池开发环境 python3开发语言 requests:发送请求,获取页面数据 lxml:使用XPATH从页面提取我们想要的书籍 pymonge:把提取到代理IP存储到MongoDB数据库中和MongoDB数据库中读取代理IP,给爬虫使用 Flask:用于提供WEB服务 代理池工作流程 1.代理池工作渡程描述: 代理IP采集模块->采集代理IP->检测代理IP->如果不可用用,直接过滤掉,如果可用,指定默认分数->存入数据库中 代理IP检测模块->从数据库中获取所有代理IP->检测代理IP->如果代理IP不可用用,就把分数-1,如果分数为0从数据库中删除,否则更新数据库,如果代理IP可用,恢复为默认分值,更新数据库 代理API模块->从数据库中高可用的代理IP给爬虫使用; ...

13 min · 6061 words · Luenci

大数据之Hadoop

Hadoop介绍 组成部分 Hadoop主要由3部分组成: Mapreduce编程模型 HDFS分布式文件存储 YARN ...

6 min · 2851 words · Luenci

妹子图爬虫(爬取妹子图图片)

python实现妹子图爬虫(爬取妹子网图片) 一个简单的小爬虫实现爬取妹子图网站上的图片。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #coding=utf-8 import requests from bs4 import BeautifulSoup import os all_url = 'http://www.mzitu.com' #http请求头 Hostreferer = { 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', 'Referer':'http://www.mzitu.com' } Picreferer = { 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', 'Referer':'http://i.meizitu.net' } #此请求头破解盗链 start_html = requests.get(all_url,headers = Hostreferer) #保存地址 path = "D:\\mzitu\\" #找寻最大页数 soup = BeautifulSoup(start_html.text,"html.parser") page = soup.find_all('a',class_='page-numbers') max_page = page[-2].text same_url = 'http://www.mzitu.com/all/' for n in range(1,int(max_page)+1): ul = same_url+str(n) start_html = requests.get(ul, headers = Hostreferer) soup = BeautifulSoup(start_html.text,"html.parser") all_a = soup.find('div',class_='all').find_all('a',target='_blank') for a in all_a: title = a.get_text() #提取文本 if(title != ''): print("准备扒取:"+title) #win不能创建带?的目录 if(os.path.exists(path+title.strip().replace('?',''))): #print('目录已存在') flag=1 else: os.makedirs(path+title.strip().replace('?','').replace(':', '')) flag=0 os.chdir(path + title.strip().replace('?','').replace(':', '')) href = a['href'] html = requests.get(href,headers = Hostreferer) mess = BeautifulSoup(html.text,"html.parser") pic_max = mess.find_all('span') try: pic_max = pic_max[9].text #最大页数 if(flag == 1 and len(os.listdir(path+title.strip().replace('?',''))) >= int(pic_max)): print('已经保存完毕,跳过') continue for num in range(1, int(pic_max)+1): pic = href+'/'+str(num) html = requests.get(pic,headers = Hostreferer) mess = BeautifulSoup(html.text,"html.parser") pic_url = mess.find('img',alt = title) print(pic_url['src']) #exit(0) html = requests.get(pic_url['src'],headers = Picreferer) file_name = pic_url['src'].split(r'/')[-1] f = open(file_name,'wb') f.write(html.content) f.close() except Exception: pass print('完成 ') print('第',n,'页完成') 原文参考:https://blog.csdn.net/baidu_35085676/article/details/68958267

2 min · 523 words · Luenci

常用的正则表达式

匹配小数 1 [0-9]{1,}[.][0-9]* 匹配整数 1 [0-9] 中文的匹配 1 [\u4e00-\u9fa5] ...

2 min · 750 words · Luenci

数据科学之数据可视化

数据可视化概述 可视化的目的,是对数据进行可视化处理,以更明确地,有效的传递信息。 数据可视化意义 数据可视化是为了从数据中寻找三个方面的信息。 模式。指数据中的规律。 关系。指数据间的相关性。 数据间的比较 数据的构成 数据的分布或联系 异常。指有问题的数据。 ...

3 min · 1460 words · Luenci

数据科学之统计学习

统计学 中心倾向 均值(常用的额) 中位数 分位数:它表示少于数据中特定百分比的一个值 众数 ...

1 min · 418 words · Luenci

查看mysql连接状况

使用mysql- uroot -p登录后 执行命令: show processlist; 查询当前数据库用户连接情况. 如果是root帐号,你能看到所有用户的当前连接. 如果是其它普通帐号,只能看到自己占用的连接. ...

2 min · 685 words · Luenci

模块、迭代器,生成器和装饰器

module模块和包的介绍 模块的介绍 python给我们提供了十分简单的方法去创建一个模块,我们只需要写一个python文件即可,也就是说写一个.py为后缀的文件。 包的介绍 简单来说,包就是多个模块的集合。当项目较大,模块较多时,我们就可以把模块放在包中,便于管理。 我们在包中一般带有__init__.py文件,随你建包的时候就默认生成。 迭代器和生成器 迭代器 迭代器只不过是一个实现迭代器协议的容器对象。它基于两个方法: next :返回容器的下一个项目 在3.x的版本中为__next__或者next(可迭代对象) __iter__ : 返回迭代器本身 迭代器可以通过使用一个iter内建函数和一个序列来创建,示例如下。 1 2 3 4 5 6 7 8 In [21]: a = ['a','b', 'c'] In [22]: a = iter(a) In [23]: next(a) Out[23]: 'a' In [24]: a.__next__() Out[24]: 'b' 生成器 生成器 从Python2.2起,生成器提供了一种出色的方法,使得需要返回一系列元素的函数所需的代码更加简单、高效。基于yield指令,可以暂停一个函数并返回中间结果。该函数将保存执行环境并且可以在必要时恢复。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 In [25]: def fibonanci(): ...: a, b = 0, 1 ...: while True: ...: yield b ...: a, b = b, a + b ...: In [26]: fib = fibonanci() In [28]: fib.__next__() Out[28]: 1 In [29]: fib.__next__() Out[29]: 1 In [30]: fib.__next__() Out[30]: 2 In [31]: fib.__next__() yield可以理解为return,每次调用next()就yield值,下次next()从上次的yield处开始运行 该函数将返回一个特殊的迭代器,也就是generator对象,它知道如何保存执行环境。对它的调用是不确定的,每次都将产生序列中的下一个元素。这种语法很简洁,算法的不确定特性并没有影响代码的可读性。不必提供使函数可停止的方法。实际上,这看上去像是用伪代码设计的序列一样。 高阶函数的定义 函数的接收参数是一个函数名 函数的返回值是一个函数名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 def father(name): print("I am father %s" %name) def son(): print("i am son") # print(locals()) return son father("luenci") father("luenci")() out: I am father luenci I am father luenci i am son 简单的装饰器 @语法糖:相当于执行下面timmer(test)() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import time def timmer(func): def wrapper(): start_time = time.time() func() sweight_time = time.time() print("函数运行时间为: %s"%(sweight_time - start_time)) return wrapper @timmer # timmer(test)() @ 语法糖 def test(): time.sleep(3) print("test函数运行完毕") test() # timmer(test)() 带参数的装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import time def timmer(func): def wrapper(*args, **kwargs): print(*args) # print(**kwargs) start_time = time.time() res = func(*args, **kwargs) sweight_time = time.time() print("程序运行时间为:%s" % (sweight_time - start_time)) return res return wrapper @timmer def test(name, age, gender): time.sleep(2) print("我是%s,今年%s,性别%s" % (name, age, gender)) return "sucess" res = test("lusheng", 18, gender="男") # print(res) 装饰器应用案例 登录验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 user_list = [ {"username": "luenci", "pswd": "123"}, {"username": "lynn", "pswd": "456"}, {"username": "lu", "pswd": "789"}, ] current_dic = {"username": None, "login": False} def verify(func): def wrapper(*args, **kwargs): if current_dic['username'] and current_dic['login']: res = func(*args, **kwargs) return res username = input("请输入用户名:").strip() pswd = input("请输入密码:").strip() for user in user_list: if user['username'] == username and user['pswd'] == pswd: current_dic['username'] = username current_dic['login'] = True res = func(*args, **kwargs) return res else: print('用户名或密码错误') return wrapper @verify def shop(): print('我的购物车') @verify def user(): print('我的信息') @verify def things(): print('我的商品') print('登录前的状态:%s'%(current_dic)) user() print('登录后的状态:%s'%(current_dic)) shop() things() 日志记录 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import logging import traceback def get_logger(): logger = logging.getLogger("Test") # 设定日志级别,只有大于或等于这个级别才输出 logger.setLevel(level=logging.DEBUG) # 当前路径下创建test_log文件记录错误日志 fh = logging.FileHandler("test_log", encoding='utf-8') ch = logging.StreamHandler() fm = logging.Formatter(fmt='%(asctime)s %(name)s %(pathname)s[%(lineno)d] %(message)s', datefmt='%Y/%m/%d %H:%M:%S') fh.setFormatter(fm) ch.setFormatter(fm) logger.addHandler(fh) logger.addHandler(ch) return logger def decoratore(func): def log(*args,**kwargs): try: print("当前运行方法", func.__name__) return func(*args,**kwargs) except Exception as e: get_logger().error(f"{func.__name__} is error,here are details:{traceback.format_exc()}") return log @decoratore def test(): print(1/0) test() ​ ...

4 min · 1572 words · Luenci