今天学习的内容如下:
1.常用模块
2.面向对象的程序设计
1. 时间模块
时间分成三种时间
1.时间戳(1970年到现在的秒数)(time.time())
2.结构化的时间(time.localtime().tm_year)
3.utc时区的时间(time.gtime())
4.格式化的时间(time.strftime('%Y-%m-%d %H:%M:%S'))
另一种形式(time.strftime('%Y-%m-%d %X'))
time.strftime('%Y',time.localtime()) (只格式化一个年出来)
time.strptime('2017-06-04 11:59:59','%Y-%m-%d %X') (把格式化时间转化成结构化时间)
time.ctime(1234453453453)
#!/usr/bin/python # -*- coding:utf-8 -*- import time #时间戳 # print(time.time()) #结构化的时间 # print(time.localtime()) # print(time.localtime().tm_year) # print(time.gmtime()) #格式化的字符串 # print(time.strftime('%Y-%m-%d %H:%M:%S')) # print(time.strftime('%Y-%m-%d %X')) # # print(time.localtime(13211123)) # print(time.localtime(time.time())) # # print(time.mktime(time.localtime())) # print(time.strftime('%Y %X',time.localtime())) # print(time.strptime('2017-06-04 11:59:59','%Y-%m-%d %X')) # print(time.ctime(123123132)) # print(time.asctime(time.localtime()))
2 random 模块
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 # import random 4 # proxy_ip=[ 5 # '1.1.1.1', 6 # '1.1.1.2', 7 # '1.1.1.3', 8 # '1.1.1.4', 9 # ] 10 # 11 # print(random.choice(proxy_ip)) 12 13 14 # import random 15 # print(random.sample([1,'23',[4,5]],2)) 16 17 import random 18 # item=[1,3,5,7,9] 19 # 20 # random.shuffle(item) 21 # print(item) 22 23 24 def v_code(n=5): 25 res='' 26 for i in range(n): 27 num=random.randint(0,9) 28 s=chr(random.randint(65,90)) 29 add=random.choice([num,s]) 30 res+=str(add) 31 return res 32 33 print(v_code(6))
3. os和sys模块
os模块是与操作系统交互的一个借口
1 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 2 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd 3 os.curdir 返回当前目录: ('.') 4 os.pardir 获取当前目录的父目录字符串名:('..') 5 os.makedirs('dirname1/dirname2') 可生成多层递归目录 6 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 7 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname 8 os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 9 os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 10 os.remove() 删除一个文件 11 os.rename("oldname","newname") 重命名文件/目录 12 os.stat('path/filename') 获取文件/目录信息 13 os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/" 14 os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" " 15 os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: 16 os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' 17 os.system("bash command") 运行shell命令,直接显示 18 os.environ 获取系统环境变量 19 os.path.abspath(path) 返回path规范化的绝对路径 20 os.path.split(path) 将path分割成目录和文件名二元组返回 21 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 22 os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素 23 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False 24 os.path.isabs(path) 如果path是绝对路径,返回True 25 os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False 26 os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False 27 os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 28 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 29 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 30 os.path.getsize(path) 返回path的大小
补充:
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 import os 5 # print(os.path.abspath('a/b/c.txt')) #E:wupeiqis17day06ac.txt 6 # print(os.path.abspath('/a/b/c.txt')) #E:ac.txt 7 8 # print(os.path.split('E:\a\c.txt')) 9 # print(os.path.dirname('E:\a\c.txt')) 10 # print(os.path.dirname('E:\a')) 11 # print(os.path.basename('E:\a\a,txt')) 12 13 # print(os.path.exists('E:\a')) 14 # print(os.path.exists('E:wupeiqis17day06')) 15 16 # print(os.path.isabs('E:\day06')) 17 # print(os.path.isabs('day06')) 18 19 # print(os.path.getsize(r'E:wupeiqis17day06 est.py')) 20 21 # print(os.path.join('a','E:\b','c.txt')) 22 # print(os.path.join('a','/b','c.txt')) #/b/c.txt 23 24 # print(os.path.normcase('c:/wIndows\system32\') ) 25 26 # print(os.path.normpath('c://windows\System32\../Temp/'))
将路径加入环境变量
1 import os 2 os.path.abspath(__file__) #取当前的绝对路径 3 4 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 sys.path.append(BASE_DIR) #添加到环境变量 6 7 第二种方式: 8 BASE_DIR=os.path.normpath(os.path.join(__file__,os.pardir,os.pardir)) 9 sys.path.append(BASE_DIR)
sys模块比较有用的
sys.argv(列表的形式,文件的路径)
打印进度条
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 # import sys 5 # 6 # print(sys.argv) 7 8 9 import sys,time 10 11 for i in range(50): 12 sys.stdout.write('%s ' %('#'*i)) 13 sys.stdout.flush() 14 time.sleep(0.1) 15 16 ''' 17 注意:在pycharm中执行无效,请到命令行中以脚本的方式执行 18 '''
代表跳到行首
4.shutil模块
高级的 文件、文件夹、压缩包 处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
1 import shutil 2 3 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
shutil.copyfile(src, dst)
拷贝文件
1 shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
1 shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
1 shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
shutil.copy(src, dst)
拷贝文件和权限
1 import shutil 2 3 shutil.copy('f1.log', 'f2.log')
shutil.copy2(src, dst)
拷贝文件和状态信息
1 import shutil 2 3 shutil.copy2('f1.log', 'f2.log')
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
1 import shutil 2 3 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
1 import shutil 2 3 shutil.rmtree('folder1')
shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。
1 import shutil 2 3 shutil.move('folder1', 'folder3')
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对象
1 #将 /data 下的文件打包放置当前程序目录 2 import shutil 3 ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data') 4 5 6 #将 /data下的文件打包放置 /tmp/目录 7 import shutil 8 ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
5. json模块
用来序列化
之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。
1 import json 2 x="[null,true,false,1]" 3 print(eval(x)) #报错,无法解析null类型,而json就可以 4 print(json.loads(x))
什么是序列化?
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
为什么要序列化?
1:持久保存状态
需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,'状态'会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。
内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。
在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。
具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。
2:跨平台数据交互
序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
如何序列化之json和pickle:
json
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
json python
{} dict
[] list
"string" str
123.56 int或float
true/false True/False
null None
内存中的结构化数据 《————》 格式json 《————》字符串 《————》 保存到文件中或基于网络传输
实例
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 dic={ 4 'name':'alex', 5 'age':9000, 6 'height':'150cm', 7 } 8 with open('a.txt','w') as f: 9 f.write(str(dic)) 10 11 12 # with open('a.txt','r') as f: 13 # res=eval(f.read()) 14 # print(res['name'],type(res)) 15 16 17 # x="[null,true,false,1]" 18 # x="[None,True,1]" 19 20 # res=eval(x) 21 # 22 # print(res[0],type(res)) 23 # import json 24 # res=json.loads(x) 25 # print(res) 26 27 import json 28 #序列化的过程:dic---->res=json.dumps(dic)---->f.write(res) 29 dic={ 30 'name':'alex', 31 'age':9000, 32 'height':'150cm', 33 } 34 35 res=json.dumps(dic) 36 print(res,type(res)) 37 with open('a.json','w') as f: 38 f.write(res) 39 40 41 42 import json 43 #反序列化的过程:res=f.read()---->res=json.loads(res)---->dic=res 44 with open('a.json','r') as f: 45 dic=json.loads(f.read()) 46 print(dic,type(dic)) 47 print(dic['name']) 48 49 50 #json的便捷操作 51 import json 52 dic={ 53 'name':'alex', 54 'age':9000, 55 'height':'150cm', 56 } 57 json.dump(dic,open('b.json','w'))
反序列化实例
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 import json 5 6 res=json.load(open('b.json','r')) 7 print(res,type(res))
6. pickle 模块
可以序列化python的任意对象
实例
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 import pickle 5 6 # dic={'name':'alex','age':13} 7 8 # print(pickle.dumps(dic)) 9 # with open('a.pkl','wb') as f: 10 # f.write(pickle.dumps(dic)) 11 12 # with open('a.pkl','rb') as f: 13 # d=pickle.loads(f.read()) 14 # print(d,type(d)) 15 16 17 18 # dic={'name':'alex','age':13} 19 # pickle.dump(dic,open('b.pkl','wb')) 20 # res=pickle.load(open('b.pkl','rb')) 21 # print(res,type(res)) 22 23 24 # 25 import json 26 import pickle 27 # def func(): 28 # print('from func') 29 30 # json.dumps(func)# 报错,json不支持python的函数类型 31 # f=pickle.dumps(func) 32 # print(f) 33 34 # pickle.dump(func,open('c.pkl','wb')) 35 # res=pickle.load(open('c.pkl','rb')) 36 # print(res) 37 # res()
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 5 import pickle 6 7 pickle.load(open('c.pkl','rb')) 8 9 ###报错 在内存空间内找不到对应的方法。因为他序列化保存的是一个内存地址,普通的数据类型是序列化的是数据类型,然后反序列化的时候又在内存空间创建。
7. shelve
python所支持的数据类型
实例:
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 # import shelve 5 # 6 # f=shelve.open(r'sheve.txt') 7 # # f['student1']={'name':'egon','age':18,'height':'180cm'} 8 # print(f['student1']['name']) 9 # f.close()
8. xml
xml协议在各个语言里都是支持的
实例1
#!/usr/bin/python # -*- coding:utf-8 -*- import xml.etree.ElementTree as ET tree = ET.parse("a") root = tree.getroot() # for i in root.iter('year'): # print(i.tag,i.text,i.attrib) # print(root.find('country')) # print(root.findall('country')) # for country in root: # print('=====>',country.attrib['name']) # for item in country: # print(item.tag,item.text,item.attrib) # for year in root.iter('year'): # print(year.tag,year.text,year.attrib) # for year in root.iter('year'): # year.text=str(int(year.text)+1) # year.set('update','yes') # tree.write('b.xml') # tree.write('a') # for country in root: # print(country) # # print('===>',country.find('year')) # year=country.find('year') # if int(year.text) > 2010: # country.remove(year) # # tree.write('d.xml') # year2 = ET.Element('year2') # for country in root: # print(country) # # print('===>',country.find('year')) # year=country.find('year') # if int(year.text) > 2010: # year2 = ET.Element('year2') # year2.text=str(int(year.text)+1) # year2.set('update','yes') # country.append(year2) # tree.write('e.xml') import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"}) age = ET.SubElement(name, "age", attrib={"checked": "no"}) sex = ET.SubElement(name, "sex") sex.text = '33' name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"}) age = ET.SubElement(name2, "age") age.text = '19' et = ET.ElementTree(new_xml) # 生成文档对象 et.write("test.xml", encoding="utf-8", xml_declaration=True) ET.dump(new_xml) # 打印生成的格式
实例2
1 import xml.etree.ElementTree as ET 2 3 tree = ET.parse("xmltest.xml") 4 root = tree.getroot() 5 print(root.tag) 6 7 #遍历xml文档 8 for child in root: 9 print('========>',child.tag,child.attrib,child.attrib['name']) 10 for i in child: 11 print(i.tag,i.attrib,i.text) 12 13 #只遍历year 节点 14 for node in root.iter('year'): 15 print(node.tag,node.text) 16 #--------------------------------------- 17 18 import xml.etree.ElementTree as ET 19 20 tree = ET.parse("xmltest.xml") 21 root = tree.getroot() 22 23 #修改 24 for node in root.iter('year'): 25 new_year=int(node.text)+1 26 node.text=str(new_year) 27 node.set('updated','yes') 28 node.set('version','1.0') 29 tree.write('test.xml') 30 31 32 #删除node 33 for country in root.findall('country'): 34 rank = int(country.find('rank').text) 35 if rank > 50: 36 root.remove(country) 37 38 tree.write('output.xml')
实例3
1 #在country内添加(append)节点year2 2 import xml.etree.ElementTree as ET 3 tree = ET.parse("a.xml") 4 root=tree.getroot() 5 for country in root.findall('country'): 6 for year in country.findall('year'): 7 if int(year.text) > 2000: 8 year2=ET.Element('year2') 9 year2.text='新年' 10 year2.attrib={'update':'yes'} 11 country.append(year2) #往country节点下添加子节点 12 13 tree.write('a.xml.swap')
实例4
1 import xml.etree.ElementTree as ET 2 3 4 new_xml = ET.Element("namelist") 5 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) 6 age = ET.SubElement(name,"age",attrib={"checked":"no"}) 7 sex = ET.SubElement(name,"sex") 8 sex.text = '33' 9 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) 10 age = ET.SubElement(name2,"age") 11 age.text = '19' 12 13 et = ET.ElementTree(new_xml) #生成文档对象 14 et.write("test.xml", encoding="utf-8",xml_declaration=True) 15 16 ET.dump(new_xml) #打印生成的格式
9. hashlib 文件校验
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 import hashlib 5 m = hashlib.md5() 6 with open('a','rb') as f: 7 for line in f: 8 m.update(line) 9 md5_num = m.hexdigest() 10 11 print(md5_num)
存在缺陷,可以通过撞库来破解
密码加盐,加一个自定义的字符串
1 import hmac 2 3 h = hmac.new('alive'.encode('utf-8')) 4 h.update('alex3714'.encode('utf-8')) 5 print(h.hexdigest()) 6 7 ####两个和到一起
10 subprocess 模块
os.system()运行命令直接返回,用subprocess可以执行命令把结果保存下来,往任意位置发送
1 import subprocess 2 #stdout 标准输出,结果扔到管道里 3 #stderr 报错信息,扔到管道里 4 #stdin 标准输入 5 res = subprocess.Popen('dir',shell=True, 6 stderr=subprocess.PIPE, 7 stdout=subprocess.PIPE) 8 res.stdout.read().decode('gbk') ##从管道里吧结果拿出来
模拟管道输入
1 import subprocess 2 # res1 把输出结果扔到管道里 3 res1 = subprocess.Popen(r'dir E:wupeiqis17day06',shell=True,stdout=subprocess.PIPE) 4 5 # res 把res1的输出结果通过stdin接受,然后去执行findstr txt*, 6 res = subprocess.Popen('findstr txt*',shell=True, 7 stdin=res1.stdout, 8 stderr=subprocess.PIPE, 9 stdout=subprocess.PIPE) 10 print(res.stdout.read().decode('gbk')) #管道只能取一次内容,取一次就空了
11 logging 日志模块
实例
1 import logging 2 logging.basicConfig( 3 format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', 4 datefmt='%Y-%m-%d %H:%M:%S %p', 5 level=10 6 ) 7 8 logging.debug('debug') 9 logging.info('info') 10 logging.warning('warning') 11 logging.error('error') 12 logging.critical('critical')
12 configparser模块
实例
1 import configparser 2 config = configparser.ConfigParser() 3 config.read('a.ini') 4 5 print(config.sections()) 6 config.get(option=('section1')) 7 config.items('section1')
13 软件开发规范
原则:目录明细,相同的功能放到同一个目录下
--ATM
--bin #执行文件
--
--conf #配置文件
--
--lib #包
--
--logs #日志
--
-- db #数据
--
--core #主逻辑
--
14 类与对象
面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。
优点是:极大的降低了程序的复杂度
缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。
面向对象的程序设计的
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性
对象就是变量与函数的结合体
面向对象唯一的优点:可扩展性强
类:提取对象共同的特征和技能就是类
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 4 # class Foo: 5 # '''文档注释''' 6 # pass 7 8 9 #类是一系列对象共有的特征(变量的定义)与技能(函数的定义)的结合体 10 # class Chinese: 11 # country='China' 12 # 13 # # Chinese.__init__(p1,'egon','18','male') 14 # def __init__(self,name,age,sex): 15 # #p1.Name=name;p1.Age=age,p1.Sex=sex 16 # self.Name=name 17 # self.Age=age 18 # self.Sex=sex 19 # 20 # 21 # def talk(self): 22 # print('talking',self) 23 24 25 #属性的引用 26 # print(Chinese.country) 27 # print(Chinese.talk) 28 # Chinese.talk(123) 29 # Chinese.x=1 30 # print(Chinese.x) 31 # Chinese.country=123123123123123 32 # print(Chinese.country) 33 34 #实例化 35 class Chinese: 36 country = 'China' 37 38 # Chinese.__init__(p1,'egon','18','male') 39 def __init__(self, name, age, sex): 40 # p1.Name=name;p1.Age=age,p1.Sex=sex 41 self.Name = name 42 self.Age = age 43 self.Sex = sex 44 def talk(self): 45 print('%s is talking' %self.Name) 46 # p1=Chinese('egon','18','male') #Chinese.__init__(p1,'egon','18','male') 47 # p2=Chinese('alex','9000','female') #Chinese.__init__(p1,'egon','18','male') 48 49 #对象的使用:只有一种,就是属性引用 50 # print(p1.Name) 51 # print(p1.Age) 52 # print(p1.Sex) 53 # print(p2.Name) 54 55 # print(p1.country) 56 # print(p2.country) 57 58 59 # p1.talk() 60 # p2.talk() 61 country = 'aaaaaaaaaa' 62 class Chinese: 63 country = 'China' 64 def __init__(self, name, age, sex): 65 # self.country=123123123123123123 66 self.Name = name 67 self.Age = age 68 self.Sex = sex 69 def talk(self): 70 print('%s is talking' %self.Name) 71 #类名称空间 72 # print(Chinese.__dict__) 73 74 75 #对象的空间 76 p1=Chinese('egon','18','male') #Chinese.__init__(p1,'egon','18','male') 77 p2=Chinese('alex','180','male') 78 79 80 # print(p1.__dict__) 81 # print(p1.Age) #p1.__dict__['Age'] 82 # print(p1.country,id(p1.country)) 83 # print(p2.country,id(p2.country)) 84 85 # print(Chinese.talk) 86 # print(p1.talk) 87 # p1.talk() #Chines.talk(p1) 88 # print(p2.talk) 89 # p2.talk()#chinese.talk(p2) 90 print(type(p1))