模块与对象(六)

1.1 random模块

import random

1.1.1 大于0且小于1之间的小数
print(random.random())

1.1.2 大于等于1且小于等于3之间的整数
print(random.randint(1,3))

1.1.3 大于等于1且小于3之间的整数
print(random.randrange(1,3))

1.1.4 1或者alex或者sb
print(random.choice([1,'alex','sb']))

1.1.5 列表元素任意2个组合
print(random.sample([1,'alex','sb'],2))

1.1.6 大于1小于4的小数,如1.927109612082716
print(random.uniform(1,4))

打乱数字顺序

l=[1,3,4,2,5]

random.shuffle(l)

print(l)

生成7位数校验码

def make_code(n):

    res=''

    for i in range(n):

        s1=str(random.randint(0,9))

        s2=chr(random.randint(65,90))

        res+=random.choice([s1,s2])

    return res

 

print(make_code(7))

1.2 os模块

os模块是与操作系统交互的一个接口

1.2.1 os.stat('path/filename')  获取文件/目录信息

print(os.stat(r'F:Python周末20期day61 本节内容').st_size)   #文件大小

1.2.2 打印系统进程,无返回值

res=os.system('tasklist')

print('====>',res)

 

1.2.3 将path分割成目录和文件名二元组返回

print(os.path.split(r'F:Python周末20期day61 本节内容'))

1.2.4 返回path的目录。其实就是os.path.split(path)的第一个元素

print(os.path.dirname(r'F:Python周末20期day61 本节内容'))

1.2.5 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素

print(os.path.basename(r'F:Python周末20期day61 本节内容'))

1.2.6 如果path是绝对路径,返回True

print(os.path.isabs(r'C:\a123sz'))

print(os.path.isabs(r'/root/a123sz'))

1.2.7 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略

print(os.path.join('C:','D:\','dir1','dir2','a.txt'))

print(os.path.join('D:\','dir1','dir2','a.txt'))

1.2.8 在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。

print(os.path.normcase('c:/windows\SYstem32\..'))

规范化路径,如..和/

print(os.path.normpath('c://windows\System32\../Temp/')) #C:windows	emp

1.2.9 os路径处理

1.2.9.1  方式一:

F:Python周末20期day63 os模块.py....

print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

1.2.9.2  方式二:

BASE_DIR=os.path.normpath(os.path.join(

    os.path.abspath(__file__),

    '..',

    '..'

))

print(BASE_DIR)

1.2.10 返回path文件的大小

print(os.path.getsize(r'F:Python周末20期day61 本节内容'))

1.2.11 常用模块

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径

os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd

os.curdir  返回当前目录: ('.')

os.pardir  获取当前目录的父目录字符串名:('..')

os.makedirs('dirname1/dirname2')    可生成多层递归目录

os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推

os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname

os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname

os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

os.remove()  删除一个文件

os.rename("oldname","newname")  重命名文件/目录

os.stat('path/filename')  获取文件/目录信息

os.sep    输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"

os.linesep    输出当前平台使用的行终止符,win下为" ",Linux下为" "

os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:

os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

os.system("bash command")  运行shell命令,直接显示

os.environ  获取系统环境变量

os.path.abspath(path)  返回path规范化的绝对路径

os.path.split(path)  将path分割成目录和文件名二元组返回

os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素

os.path.basename(path)  返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素

os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False

os.path.isabs(path)  如果path是绝对路径,返回True

os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False

os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False

os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略

os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间

os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

os.path.getsize(path) 返回path的大小

1.3 sys模块

sys.argv           命令行参数List,第一个元素是程序本身路径

sys.exit(n)        退出程序,正常退出时exit(0)

sys.version        获取Python解释程序的版本信息

sys.maxint         最大的Int值

sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

sys.platform       返回操作系统平台名称

import sys

sys.argv

sys.exit(0)

sys.path

进度条的效果制定宽度

print('[%-50s]' %('#'*1))

print('[%-50s]' %('#'*2))

print('[%-50s]' %('#'*3))

print('[%-50s]' %('#'*4))

print('[%-50s]' %('#'*5))

打印%

([%-50s]) %('#'*10)

print('[%%-%ds]' %50) #'[%-50s]'

可传参来控制宽度

print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)

print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)

print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)

print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)
打印%
print('%d%%' %30)

1.3.1 进度条功能

import time 

#指定宽度

print('[%-15s]' %'#')

print('[%-15s]' %'##')

print('[%-15s]' %'###')

print('[%-15s]' %'####') 

#打印%

print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义 

#可传参来控制宽度

print('[%%-%ds]' %50) #[%-50s]

print(('[%%-%ds]' %50) %'#')

print(('[%%-%ds]' %50) %'##')

print(('[%%-%ds]' %50) %'###')

#实现打印进度条函数

import sys

import time

 

def progress(percent,width=50):

    if percent >= 1:

        percent=1

    show_str=('[%%-%ds]' %width) %(int(width*percent)*'#')

    print('
%s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')

 

应用

def progress(percent,width=50): #进度条的宽度70

    if percent >= 1:

        percent=1

    show_str = ('[%%-%ds]' % width) % ('#' * int(width*percent))

    print('
%s %d%%' %(show_str,int(100*percent)),end='')

 

recv_size=0

total_size=10241

while recv_size < total_size:

    time.sleep(0.1) #模拟数据的传输延迟

    recv_size+=1024 #每次收1024

    progress(recv_size/total_size) #接收的比例

1.4 shutil模块

高级的 文件、文件夹、压缩包 处理模块

1.4.1 shutil.copyfileobj(fsrc, fdst[, length])

将文件内容拷贝到另一个文件中

import shutil

shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

shutil.copyfile(src, dst)

1.4.2 拷贝文件

shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在

shutil.copymode(src, dst) 仅拷贝权限。内容、组、用户均不变

shutil.copymode('f1.log', 'f2.log') #目标文件必须存在

shutil.copystat(src, dst) 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

shutil.copystat('f1.log', 'f2.log') #目标文件必须存在

1.4.2.1  shutil.copy(src, dst)

import shutil

shutil.copy('f1.log', 'f2.log') 拷贝文件和权限

import shutil

shutil.copy2('f1.log', 'f2.log') 拷贝文件和状态信息 

1.4.2.2  shutil.ignore_patterns(*patterns)

shutil.copytree(src, dst, symlinks=False, ignore=None)

递归的去拷贝文件夹

import shutil

shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 

1.4.2.3  拷贝软连接

import shutil

 

shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

'''

通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件

'''

1.4.3 shutil.rmtree(path[, ignore_errors[, onerror]])

递归的去删除文件

import shutil

shutil.rmtree('folder1')

1.4.4 shutil.move(src, dst)

递归的去移动文件,它类似mv命令,其实就是重命名。

import shutil

shutil.move('folder1', 'folder3')

 

1.4.5 压缩解压缩

1.4.5.1  shutil.make_archive(base_name, format,...)

创建压缩包并返回文件路径,例如:zip、tar

创建压缩包并返回文件路径,例如:zip、tar

base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,

如 data_bak                       =>保存至当前路径

如:/tmp/data_bak =>保存至/tmp/

format:      压缩包种类,“zip”, “tar”, “bztar”,“gztar”

root_dir:    要压缩的文件夹路径(默认当前目录)

owner:       用户,默认当前用户

group: 组,默认当前组

logger:       用于记录日志,通常是logging.Logger对象

import shutil

shutil.make_archive("bak", 'gztar', root_dir=r'F:Python周末20期day6') #tar cvzf bak.tar.gz /root

#将 /data 下的文件打包放置当前程序目录

import shutil

ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')

#将 /data下的文件打包放置 /tmp/目录

import shutil

ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')

1.4.5.2  zipfile压缩解压缩

import zipfile

 

# 压缩

z = zipfile.ZipFile('laxi.zip', 'w')

z.write('a.log')

z.write('data.data')

z.close()

 

# 解压

z = zipfile.ZipFile('laxi.zip', 'r')

z.extractall(path='.')

z.close()

1.4.5.3  tarfile压缩解压缩

import tarfile

 

# 压缩

>>> t=tarfile.open('/tmp/egon.tar','w')

>>> t.add('/test1/a.py',arcname='a.bak')

>>> t.add('/test1/b.py',arcname='b.bak')

>>> t.close()

压缩

import tarfile

t=tarfile.open('bak.tar.gz')

t.extractall(r'F:Python周末20期day6aaa')

t.close()

 

# 解压

>>> t=tarfile.open('/tmp/egon.tar','r')

>>> t.extractall('/egon')

>>> t.close()

 

1.5 jison和pickle模块

之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值

dic={'a':1}

 

with open('db.txt','w',encoding='utf-8') as f:

    f.write(str(dic))

 

with open('db.txt','r',encoding='utf-8') as f:

    dic=eval(f.read()) #"{'a':1}"

    print(dic['a'])

打印报错

eval("[null,false,1]")

无法解析null类型,而json就可以

import json

dic={'a':1}

x=None

 

res1=json.dumps(dic) #str(dic)

res2=str(dic)

print(res1,type(res1))

print(res2,type(res2))

 

res=json.dumps(x)

print(res,type(res))

1.5.1 json序列化

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

 

图1-1  

 

图1-2  

import json,time

user={'name':'egon','age':18,'nb':True}

with open('user.json','w',encoding='utf-8') as f:

    f.write(json.dumps(user))  #等价于json.dump(dic,f)

 

students=['alex','egon','wxx','yxx']

json.dump(students,open('students.json','w',encoding='utf-8'))

 

time.sleep(500)

 

1.5.2 pickle

 

图1-3  

Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

import pickle,json

import pickle,json

 

s={1,2,3}

print(json.dumps(s))

print(pickle.dumps(s))

 

with open('s.pkl','wb') as f:  #注意是w是写入str,wb是写入bytes,j是'bytes'

    f.write(pickle.dumps(s))

 

pickle.dump(s,open('s.pkl','wb'))

1.5.3 json反序列化

with open('s.pkl','rb') as f:

    s=pickle.loads(f.read()) #等价于s=pickle.load(f)

    print(s,type(s))

 

s=pickle.load(open('s.pkl','rb'))

print(s, type(s))

无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads

1.6 shelve模块

shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型

import shelve

 

f=shelve.open('db.shl')

# f['stu1']={'name':'alex1','age':38}

# f['stu2']={'name':'alex2','age':28}

print(f['stu1']['name'])

f.close()

1.7 xml模块

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

xml数据

<?xml version="1.0"?>

<data>

    <country name="Liechtenstein">

        <rank updated="yes">2</rank>

        <year>2008</year>

        <gdppc>141100</gdppc>

        <neighbor name="Austria" direction="E"/>

        <neighbor name="Switzerland" direction="W"/>

    </country>

    <country name="Singapore">

        <rank updated="yes">5</rank>

        <year>2011</year>

        <gdppc>59900</gdppc>

        <neighbor name="Malaysia" direction="N"/>

    </country>

    <country name="Panama">

        <rank updated="yes">69</rank>

        <year>2011</year>

        <gdppc>13600</gdppc>

        <neighbor name="Costa Rica" direction="W"/>

        <neighbor name="Colombia" direction="E"/>

    </country>

</data>

xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

# print(root.iter('year')) #全文搜索

# print(root.find('country')) #在root的子节点找,只找一个

# print(root.findall('country')) #在root的子节点找,找所有

from xml.etree import ElementTree

 

tree=ElementTree.parse('a.xml')

 

root=tree.getroot()

print(root.tag)

print(root.attrib)

print(root.text)

三种查找方式

从子节点中找

print(root.find('country'))

print(root.findall('country'))

print(root.find('rank')) #None

从正树形结构中查找

print(list(root.iter('rank')))

 

for country in root.findall('country'):

    rank=country.find('rank')

    print(rank.tag,rank.attrib,rank.text)

 

遍历文档树

for country in root:

    print('=============>',country.attrib['name'])

    for item in country:

        print(item.tag,item.attrib,item.text)

 

 

for year in root.iter('year'):

    print(year.tag,year.attrib,year.text)

 

 

for year in root.iter('year'):

    year.set('updated',"yes")

    year.text=str(int(year.text)+1)

 

tree.write('a.xml')

#在country内添加(append)节点

for country in root:

    obj=ElementTree.Element('egon') #<egon name="egon" age="18">egon is good</egon>

    obj.attrib={'name':'egon','age':'18'}

    obj.text='egon is good'

    country.append(obj)

 

tree.write('a.xml')

 

for rank in root.iter('rank'):

    if int(rank.text) == 5:

        obj=ElementTree.Element('egon') #<egon name="egon" age="18">egon is good</egon>

        obj.attrib={'name':'egon','age':'18'}

        obj.text='egon is good'

        rank.append(obj)

 

tree.write('a.xml')

1.8 configerparser模块

import configparser

 

config=configparser.ConfigParser()

config.read('my.ini')

#查看所有的标题

print(config.sections())

#查看标题mysqld下所有key=value的key

print(config.options('mysqld'))

#查看标题mysqld下charater-server-set的值=>字符串格式

print(config.get('mysqld','charater-server-set'))

 

if config.has_option('mysqld','aaa'):

    print(config.get('mysqld','aaa'))

查看标题mysqld下'skip-grant-table的值=>布尔值格式

print(config.getboolean('mysqld','skip-grant-table'))

查看标题mysqld'下port的值=>整数格式

print(config.getint('mysqld','port'))

查看标题mysqld'下port的值=> >浮点型格式
print(config.getfloat('mysqld','port'))

添加一个标题

config.add_section('egon')

在标题egon下添加name=egon,age=18的配置

config.set('egon','name','egon')

config.set('egon','age','18')

config.set('client','password','alex3714')

最后将修改的内容写入文件,完成最终的修改

config.write(open('my.ini','w',encoding='utf-8'))

1.9 hashlib模块

hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

1.9.1 三个特点:

1.内容相同则hash运算结果相同,内容稍微改变则hash值则变

2.不可逆推

3.相同算法:无论校验多长的数据,得到的哈希值长度固定。

m=hashlib.md5()

m.update('hello'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

m.update('world'.encode('utf-8'))

print(m.hexdigest())

 

fc5e038d38a57032085441e7fe7010b0

 

 

m=hashlib.md5()

m.update('hello'.encode('utf-8'))

m.update('world'.encode('utf-8'))

print(m.hexdigest())

 

m1=hashlib.md5()

m1.update('hellowor'.encode('utf-8'))

m1.update('l'.encode('utf-8'))

m1.update('d'.encode('utf-8'))

print(m1.hexdigest()) 
注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
18 但是update多次为校验大文件提供了可能。
name=input('user:>> ')

pwd=input('password:>> ')

m=hashlib.md5()

m.update(pwd.encode('utf-8'))

pwd=m.hexdigest()

 

print(name,pwd)

1.9.2 模拟撞库

cryt_pwd='aee949757a2e698417463d47acac93df'

pwds=[

    'alex3714',

    'alex123',

    '123alex'

]

def make_dic(pwds):

    dic={}

    for pwd in pwds:

        m=hashlib.md5(pwd.encode('utf-8'))

        dic[pwd]=m.hexdigest()

    return dic

 

dic=make_dic(pwds)

for pwd in dic:

    if dic[pwd] == cryt_pwd:

        print(pwd)

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密

import hashlib

 

m=hashlib.sha512()

m=hashlib.md5('一行白鹭上青天'.encode('utf-8'))

m.update('alex3714'.encode('utf-8'))

m.update('两个黄鹂鸣翠柳'.encode('utf-8'))

print(m.hexdigest())

python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密:
import hmac

m=hmac.new('加盐'.encode('utf-8'))

m.update('alex3714'.encode('utf-8'))

print(m.hexdigest())

#要想保证hmac最终结果一致,必须保证:

#1:hmac.new括号内指定的初始key一样

#2:无论update多少次,校验的内容累加到一起是一样的内容

import hmac

 

h1=hmac.new(b'egon')

h1.update(b'hello')

h1.update(b'world')

print(h1.hexdigest())

 

h2=hmac.new(b'egon')

h2.update(b'helloworld')

print(h2.hexdigest())

 

h3=hmac.new(b'egonhelloworld')

print(h3.hexdigest())

 

'''

f1bf38d054691688f89dcd34ac3c27f2

f1bf38d054691688f89dcd34ac3c27f2

bcca84edd9eeb86f30539922b28f3981

'''

1.10 subprocess模块

import subprocess

import time

 

subprocess.Popen('tasklist',shell=True)

print('----->主')

time.sleep(1)

 

import time

import subprocess

 

 

obj=subprocess.Popen('tasklist',shell=True,

                 stdout=subprocess.PIPE,

                 stderr=subprocess.PIPE,

                 )

print(obj)

print('第1次:',obj.stdout.read())

print('第2次:',obj.stdout.read())

print('---->主')

 

print(obj.stdout.read().decode('gbk'))

 
#等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
import subprocess #ls /etc ;pwd;ps aux

obj=subprocess.Popen('tssssasklist',shell=True,

                 stdout=subprocess.PIPE,

                 stderr=subprocess.PIPE,

                 )

 

print(obj.stdout.read())

print(obj.stderr.read().decode('gbk'))

 

了解

import subprocess #tasklist | findstr python

obj=subprocess.Popen('tasklist | findstr python',shell=True,

                 stdout=subprocess.PIPE,

                 stderr=subprocess.PIPE,

                 )

 

print(obj.stdout.read())

 

 

obj1=subprocess.Popen('tasklist',shell=True,

                 stdout=subprocess.PIPE,

                 stderr=subprocess.PIPE,

                 )

 

obj2=subprocess.Popen('findstr python',shell=True,

                 stdin=obj1.stdout,

                 stdout=subprocess.PIPE,

                 stderr=subprocess.PIPE,

                 )

 

print(obj2.stdout.read())  #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码

面向对象

1.11 类的定义与使用

1.11.1 面向过程与面向对象

    面向过程:核心是过程二字,过程即解决问题的步骤,就是先干什么再干什么

    基于该思想写程序就好比在设计一条流水线,是一种机械式的思维方式

    优点:复杂的过程流程化,进而简单化

    缺点:扩展性差

    面向对象:核心是对象二字,对象是特征与技能的结合体

    基于该思想编写程序就好比在创造一个世界,世界是由一个个对象组成,是一种“上帝式”的思维方式

    优点:可扩展性强

    缺点:编程复杂高,容易出现过度设计

1.11.2 类

    对象是特征与技能的结合体,类就是一系列对象相似的特征与技能的结合体

    在现实世界中:一定是先有的一个个具体存在的对象,后总结出的类

    在程序中:一定保证先定义类,后产生对象

1.11.3 站在老男孩学校的角度

现实中的对象:

    对象1:

        特征

            学校=老男孩

            名字=李三炮

            性别=男

            年龄=18

        技能

            学习

            选课

    对象2:

        特征

            学校=老男孩

            名字=张铁蛋

            性别=女

            年龄=38

        技能

            学习

            选课

    对象3:

        特征

            学校=老男孩

            名字=武大郎

            性别=男

            年龄=28

        技能

            学习

            选课

    对象4:

        特征

            学校=老男孩

            名字=egon

            性别=男

            年龄=18

        技能

            教学

现实中的老男孩学生类:

    老男孩学生类

        相似的特征

            学校=老男孩

        相似的技能

            学习

            选课

'''

# 类体代码在类的定义阶段就会立刻执行,

class Student:

    school='oldboy'

 

    def learn(self):

        print('is learning')

 

    def choose_course(self):

        print('choose course')

 

    # print('====run')

 

 

# print(Student)

# print(Student.__dict__)

 

#查看

# print(Student.school) #数据属性

# print(Student.learn) #函数属性

 

#增加

# Student.country='China'

# print(Student.country)

 

#修改

# Student.school='Oldboy'

# print(Student.school)

 

#删除

# del Student.country

# print(Student.country)

 

# print(Student.learn)

# Student.learn('xxxxx')

 

1.12 对象的定义与使用

1.12.1 面向过程与面向对象

    面向过程:核心是过程二字,过程即解决问题的步骤,就是先干什么再干什么

    基于该思想写程序就好比在设计一条流水线,是一种机械式的思维方式

    优点:复杂的过程流程化,进而简单化

    缺点:扩展性差

    面向对象:核心是对象二字,对象是特征与技能的结合体

    基于该思想编写程序就好比在创造一个世界,世界是由一个个对象组成,是一种“上帝式”的思维方式

    优点:可扩展性强

    缺点:编程复杂高,容易出现过度设计

1.12.2 类

    对象是特征与技能的结合体,类就是一系列对象相似的特征与技能的结合体

    在现实世界中:一定是先有的一个个具体存在的对象,后总结出的类

    在程序中:一定保证先定义类,后产生对象

1.12.3 站在老男孩学校的角度

现实中的对象:

    对象1:

        特征

            学校=老男孩

            名字=李三炮

            性别=男

            年龄=18

        技能

            学习

            选课

    对象2:

        特征

            学校=老男孩

            名字=张铁蛋

            性别=女

            年龄=38

        技能

            学习

            选课

    对象3:

        特征

            学校=老男孩

            名字=武大郎

            性别=男

            年龄=28

        技能

            学习

            选课

    对象4:

        特征

            学校=老男孩

            名字=egon

            性别=男

            年龄=18

        技能

            教学

现实中的老男孩学生类:

    老男孩学生类

        相似的特征

            学校=老男孩

        相似的技能

            学习

            选课

'''

class Student:

    school='oldboy'

 

    #stu1,'李三炮','男',18

    def __init__(self,name,sex,age): #在调用类时会自动触发执行

        self.Name=name

        self.Sex=sex

        self.Age = age

 

        #stu1.Name='李三炮'

        #stu1.Sex='男'

        #stu1.Age=18

 

    def learn(self):

        print('is learning')

 

    def choose_course(self):

        print('choose course')

 

#调用类的过程又称之为实例化:stu1=Student('李三炮','男',18)

#1、得到一个返回值,即对象,该对象是一个空对象stu1

#2、Student.__init__(stu1,'李三炮','男',18)

 

stu1=Student('李三炮','',18)

# print(stu1.__dict__)

# print(stu1.Name,stu1.Age,stu1.Sex)

 

stu2=Student('张铁蛋','',38)

stu3=Student('武大郎','',28)

# print(stu2.__dict__)

# print(stu3.__dict__)

 

# print(stu1,stu2,stu3)

 

# print(stu2.Name)

1.13 属性查找与绑定方法

x=1

class Student:

    school='oldboy'

    # Name='xxx'

 

    def __init__(self,name,sex,age): #在调用类时会自动触发执行

        self.Name = name

        self.Sex = sex

        self.Age = age

 

 

        #stu1.Name='李三炮'

        #stu1.Sex='男'

        #stu1.Age=18

 

    def learn(self,x,y):

        print('%s is learning' %self.Name)

        print(x,y)

 

    def choose_course(self):

        print('choose course')

 

    def commit_hw():

        print('commit homework')

 

1.13.1 查找一个对象的属性顺序是:先找对象自己的__dict__,再找类的__dict__

# stu1=Student('李三炮','男',18)

# # print(stu1.__dict__)

#

# # print(stu1.Name)

# # print(stu1.school)

# # print(stu1.x)

 

stu1=Student('李三炮','',18)

stu2=Student('张铁蛋','',38)

stu3=Student('武大郎','',28)

 

1.13.2 类的数据属性是所有对象共享,所有对象都指向同一个内存地址

# stu1.school='xxx'

# Student.school='Oldgirl'

# print(Student.school,id(Student.school))

# print(stu1.school,id(stu1.school))

# print(stu2.school,id(stu2.school))

# print(stu3.school,id(stu3.school))

 

# 3、类中定义的函数是绑定给对象使用:

# 3.1:不同对象就是不同绑定方法

# 3.2:绑定给谁,就应该由谁来调用,谁来调用就会把谁当做第一个参数传给对应的函数

# print(Student.learn)

# print(stu1.learn)

# print(stu2.learn)

# print(stu3.learn)

 

# stu1.learn(1,2) #Student.learn(stu1,1,2)

# stu2.learn(1,3)

# stu3.learn(1,4)

# print(Student.learn)

 

# stu1.commit_hw()

1.13.3 小练习

class Teacher:

    school='oldboy'

    count=0

 

    def __init__(self,name,sex,age,level,salary):

        self.name=name

        self.sex=sex

        self.age=age

        self.level=level

        self.salary=salary

        Teacher.count+=1

 

    def teach(self):

        print('%s is teaching' %self.name)

 

t1=Teacher('egon','male',18,10,3000)

t2=Teacher('alex','female',38,9,30000)

t3=Teacher('wxx','female',28,10,30000)

 

print(t1.count)

print(t2.count)

print(t3.count)
class Garen:

    camp='demacia'

    def __init__(self,nickname,life_value,aggresivity):

        self.nickname=nickname

        self.life_value=life_value

        self.aggresivity=aggresivity

 

    def attack(self,enemy):

        enemy.life_value-=self.aggresivity

 

 

class Riven:

    camp = 'Noxus'

 

    def __init__(self, nickname, life_value, aggresivity):

        self.nickname = nickname

        self.life_value = life_value

        self.aggresivity = aggresivity

 

    def attack(self, enemy):

        enemy.life_value -= self.aggresivity

 

    def fire(self,enemy):

        enemy.life_value-=100

 

g1=Garen('草丛猥琐男',1000,100)

r1=Riven('猛男雯雯',200,500)

print(r1.life_value)

g1.attack(r1)

print(r1.life_value)

 

1.14 类即类型

# class Teacher:

#     school='oldboy'

#     count=0

#

#     def __init__(self,name,sex,age,level,salary):

#         self.name=name

#         self.sex=sex

#         self.age=age

#         self.level=level

#         self.salary=salary

#         Teacher.count+=1

#

#     def teach(self):

#         print('%s is teaching' %self.name)

#

# t1=Teacher('egon','male',18,10,3000)

# print(type(t1))

 

# l=[1,2,3,4] #l=list([1,2,3,4])

# print(type(l))

 

l1=list([1,2,3,4])

l2=list([1,2,3,4])

# print(id(l1))

# print(id(l2))

 

# print(l1.append)

# l1.append(5) #list.appent(l1,5)

# list.append(l1,5)

# print(l1)

 

l1.append('a')

l2.append('b')

1.15 从代码级别看面向对象

1.15.1 在没有学习类这个概念时,数据与功能是分离的

def exc1(host,port,db,charset,sql):

    conn=connect(host,port,db,charset)

    res=conn.execute(sql)

    return res

 

def exc2(host,port,db,charset,proc_name)

    conn=connect(host,port,db,charset)

    res=conn.call_proc(prco_name)

    return res

 

#每次调用都需要重复传入一堆参数

exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')

exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')

 

exc1('127.0.0.1',3306,'db1','utf8','select * from tb2;')

1.15.2 在没有学习类这个概念时,数据与功能是分离的

host='127.0.0.1'

port=3306

db='db1'

charset='utf-8'

 

x=1

y=2

 

def exc1(sql):

    conn=connect(host,port,db,charset)

    res=conn.execute(sql)

    return res

 

def exc2(proc_name)

    conn=connect(host,port,db,charset)

    res=conn.call_proc(prco_name)

    return res

 

def func1():

    print(x)

    print(y)

 

def func2():

    print(x)

    print(y)

#每次调用都需要重复传入一堆参数

exc1('select * from tb1;')

exc2('utf8','存储过程的名字')

 

exc1('select * from tb2;')

 

func()

1.15.3 使用类

# class Mysqlhandle:

#     def __init__(self,host,port,db,charset='utf-8'):

#         self.host=host

#         self.port=port

#         self.db=db

#         self.charset=charset

#         self.conn=connect(host,port,db,charset)

#

#     def exc1(self,sql):

#         return self.conn.execute(sql)

#

#     def exc2(self,proc_name)

#         return self.conn.call_proc(prco_name)

#

# obj1=Mysqlhandle('127.0.0.1',3306,'db1')

#

# obj1.exc1('select * from t1')

# obj1.exc1('select * from t2')

# obj1.exc1('select * from t3')

 

# obj2=Mysqlhandle('10.10.10.9',3306,'db2')

# obj2.exc1('select * from t1 where id > 3')
原文地址:https://www.cnblogs.com/x-y-j/p/8313170.html