# 静态属性 、 对象属性、 方法(动态属性) 前面加上双下划綫都会变成私有的
# 私有的特点就是只能在类的内部调用,不能在类的外部使用!!
面试题 in Foo
1 # class Foo:
2 # def __init__(self):
3 # self.__func() # self._Foo__func
4 # def __func(self):
5 # print('in Foo')
6 #
7 # class Son(Foo):
8 # def __func(self): # _Son__func
9 # print('in son')
10 #
11 # s = Son()
inFoo
1 # class Foo:
2 # def __init__(self):
3 # self.func()
4 # def func(self):
5 # print('in Foo')
6
7 # class Son(Foo):
8 # def func(self):
9 # print('in son')
10 #
11 # s = Son()
inson
二、类中的装饰器方法:
三个装饰器函数:classmethod staticmethod property(将一个函数伪装成属性 @property 重要)
圆形类 面积 打折--修改删除不常用 property 必须掌握
1 from math import pi
2 class Circle:
3 def __init__(self,r):
4 self.r=r
5 @property
6 def area(self):
7 print('area被执行了...')
8 return self.r**2*pi
9 @property
10 def perimeter(self):
11 return self.r*2*pi
12 # # 方法 动词 —— 动作或者技能
13 # # 名词 圆的面积 圆的周长 圆的班级
14 #将一个函数伪装成属性 @property
15
16 c=Circle(3)
17 print(c.area)
18 print(c.perimeter)
圆形类
1 # #练习计算面积--zijixiede
2 # class mj:
3 # def __init__(self,l,h):
4 # self.l=l
5 # self.h=h
6 # @property
7 # def area(self):
8 # return self.h *self.l
9 # ss=mj(2,3)
10 # print(ss.area)
计算面积
1 #property 和 __私有的名字一起使用----------打折例子
2
3 class Goods:
4 def __init__(self,price,discount):
5 self.__price=price
6 self.discount=discount
7 @property
8 def price(self):
9 return self.__price * self.discount
10 @price.setter #修改价格
11 def price(self,newprice):
12 self.__price=newprice
13 @price.deleter #删除
14 def price(self):
15 del self.__price
16
17 apple=Goods(8,0.7)
18 print(apple.price)
19 apple.price=10
20 print(apple.price)
21 print(apple.__dict__)
22 del apple.price
23 print(apple.__dict__)
24 # print(apple.price)
25
26 结果:
27 5.6
28 7.0
29 {'_Goods__price': 10, 'discount': 0.7}
30 {'discount': 0.7}
打折例子
国籍例子--classmethod 变成类方法。使用场景:# 如果某一个类中的方法 并没有用到这个类的实例中的具体属性
# 只是用到了类中的静态变量 就使用类方法
1 # class Person:
2 # Country = '中国人'
3 # @classmethod #把func变成了一个类方法
4 # def func(cls): # cls是指向类的内存空间
5 # print('当前的角色的国籍是%s'%cls.Country)
6
7 # alex = Person()
8 # alex.func()
9 # Person.func()
10 # 如果某一个类中的方法 并没有用到这个类的实例中的具体属性
11 # 只是用到了类中的静态变量 就使用类方法
View Code
登录例子--如果一个方法,既不会用到对象中的属性也不会用到类中的属性,就应该被定义为一个静态方法 staticmethod
1 class Student:
2 @staticmethod
3 def login():
4 name = input('name : ')
5 pwd = input('pwd : ')
6 if name =='' and pwd =='':
7 print('实例化')
8
9 Student.login()
staticmethod
三、序列化模块 非常重要
1.什么叫序列化:数据类型-->字符串的过程
2.用序列化情况:固态存储;网络传输
3.模块:
json 通用的 支持的数据类型 list tuple dict
pickle python中通用的 ,支持几乎所有python中的数据类型
shelve python中使用的便捷的序列化工具
4个方法 及例子
dumps 内存中做操作 字典转字符串的过程 ——序列化
loads 内存中做操作 字符串 转回其他数据类型 —— 反序列化
dump 和文件交互 一次性写的数据,只能一次性读出
load 从文件中反序列化 不能多次load解决办法:
如果要dump多条数据,每一条数据先dumps一下 编程字符串 然后打开文件 write写进文件里
读取的时候按照标志读取或者按行读
读出来之后,再使用loads
1 # 什么叫序列化呢?
2 # { '10100011':{'name':,age: ,class:},}
3 # 数据类型 —— 字符串的过程
4 # 什么时候要用序列化呢?
5 # 数据从内存到文件
6 # 数据在网络上传输 字节 - 字符串 - 字典
7 # python中的序列化模块都有哪些?
8 # json 通用的 支持的数据类型 list tuple dict
9 # pickle python中通用的 支持几乎所有python中的数据类型
10 # shelve python中使用的便捷的序列化工具
11
12 # dumps loads
13 # dump load
14
15 import json
16 dic = {"k":'v'}
17 # print(type(dic))
18 # json_dic = json.dumps(dic) #{"k": "v"} # 字典转字符串的过程 ——序列化
19 # print(json_dic)
20 # print(dic) #{'k': 'v'}
21 # print(type(json_dic))
22 # print(json.loads(json_dic)) # 字符串 转回其他数据类型 —— 反序列化
23
24 # with open('d','w') as f:
25 # json.dump(dic,f) # dump是和文件交互的
26 # json.dump(dic,f) # dump是和文件交互的
27
28 # with open('d') as f:
29 # print(json.load(f)) # 从文件中反序列化
30
31 # 如果要dump多条数据
32 # 每一条数据先dumps一下 编程字符串 然后打开文件 write写进文件里
33 # 读取的时候按照标志读取或者按行读
34 # 读出来之后 再使用loads
概念
例子
# with open('aaa','w') as f:
# str_dic = json.dumps(dic)
# f.write(str_dic+'
')
# f.write(str_dic+'
')
# f.write(str_dic+'
')
# f.write(str_dic+'
')
# with open('aaa') as f:
# for line in f:
# print(json.loads(line.strip()))
例子
pickle 对象序列化文件 例子 打印出显示二进制类型的,要以wb打开,要以rb去读
dump,load取值就行,加异常处理
1 # import pickle
2 # class A:
3 # def __init__(self,name):
4 # self.name = name
5 #
6 # alex = A('alex')
7 # print(pickle.dumps(alex))
8 # with open('bbb','wb') as f:
9 # pickle.dump(alex,f)
10 # pickle.dump(alex,f)
11 # pickle.dump(alex,f)
12 #
13 # with open('bbb','rb') as f:
14 # while True:
15 # try:
16 # obj = pickle.load(f)
17 # print(obj.name)
18 # except EOFError:
19 # break
pickle例子
pickle与json区别
1.pickle支持更多的数据类型
2.pickle的结果是二进制
3.pickle在和文件交互的时候可以被多次load
shelve读博客--不常用 不能同时进行写操作
网络传输
四、三个模块
1.hashlib模块 重要 摘要算法 单向不可逆
2.logging模块 重要
3.configparse模块 一般
1.hashlib模块:以后登录都要加密密码!!!
作用1:存储用户密码的时候,不要存储明文
包含了多种算法的模块
将一个字符串进行摘要运算,拿到一个不变的 固定长度的值
md5算法:32位
sha算法:数字越大,越复杂,时间越长,结果越长 sha1 40位
import hashlib
#hashlib.md5()#<md5 HASH object @ 0x000000000218C8A0>一种算法
md5obj=hashlib.md5() #实例化一个md5摘要算法的对象
# 能够让一个字符串 唯一的 对应一个固定的值
md5obj.update('lijie123'.encode('utf-8')) #使用md5算法的对象来操作字符串
#获取算法的结果
ret=md5obj.hexdigest()
print(ret,type(ret),len(ret))
View Code
撞库 别人有一个庞大的库,存储了很多字符串和MD5值得关系
有了加盐 例子
动态加盐 userinfo表 把username作为盐 例子
作用2:校验文件一致性
分多次对一个文件进行摘要结果一致
练习题:。。。
1 # 登录 —— hashilib
2 # 数据库泄露
3 # 存储用户密码的时候 : 不要存储明文
4 # 对用户输入的密码进行一种计算 计算之后 会得到一个新的 固定的 字符串
5
6 # hashlib模块 摘要算法 ---> 单向不可逆
7 # 包含了多种算法
8 # 将一个字符串进行摘要运算 拿到不变的 固定长度的值
9 # import hashlib
10 # md5obj = hashlib.md5() # 实例化一个md5摘要算法的对象
11 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串
12 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化
13 # print(ret,type(ret),len(ret))
14 # 注册 :alex3714 -摘要-> 文件里
15 # 登录 :alex3714 -摘要-> 和文件里比对
16 # md5obj = hashlib.sha1() # 实例化一个md5摘要算法的对象
17 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串
18 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化
19 # print(ret,type(ret),len(ret))
20
21 # 撞库
22 # 别人有一个庞大的库 :字符串 --> md5值的关系
23 # 加盐
24 # md5obj = hashlib.md5('tesla'.encode('utf-8')) # 实例化一个md5摘要算法的对象,加盐
25 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串
26 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化
27 # #aee949757a2e698417463d47acac93df
28 # print(ret)
29
30 # 动态加盐
31 # userinfo表
32 # username = 'alex'
33 # md5obj = hashlib.md5(username.encode('utf-8')) # 实例化一个md5摘要算法的对象,加盐
34 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串
35 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化
36 # #aee949757a2e698417463d47acac93df
37 # print(ret)
38
39 # 校验文件一致性
40 # 自动化 —— python代码来做验证
41 # import hashlib
42 # md5obj = hashlib.md5() # 实例化一个md5摘要算法的对象
43 # md5obj.update('alex'.encode('utf-8')) # 使用md5算法的对象来操作字符串
44 # md5obj.update('3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串
45 # print(md5obj.hexdigest())
46
47 # aee949757a2e698417463d47acac93df
48 # aee949757a2e698417463d47acac93df
49
50 # 写一个函数 接收两个文件的地址 返回T/F
课上笔记
2.configparse模块 一般
快速处理配置文件 创建 实例化-字典
查看 default 类似于全局变量
用到的时候去博客中查看即可
1 import configparser
2
3 # config = configparser.ConfigParser()
4 # config["DEFAULT"] = {'ServerAliveInterval': '45',
5 # 'Compression': 'yes',
6 # 'CompressionLevel': '9',
7 # 'ForwardX11':'yes'
8 # }
9 #
10 # config['bitbucket.org'] = {'User':'hg'}
11 # config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'}
12 # with open('example.ini', 'w') as f:
13 # config.write(f)
14
15 import configparser
16
17 config = configparser.ConfigParser()
18 print(config.sections())
19 config.read('example.ini')
20 print(config.sections()) # ['bitbucket.org', 'topsecret.server.com'] # DEFAULT --> 全局
21
22 # print('bytebong.com' in config) # False
23 # print('bitbucket.org' in config) # True
24 # print(config['bitbucket.org']["user"]) # hg
25 # print(config['DEFAULT']['Compression']) #yes
26 # print(config['topsecret.server.com']['ForwardX11']) #no
27 # print(config['bitbucket.org']) #<Section: bitbucket.org> 生成器
28 # for key in config['bitbucket.org']: # 注意,有default会默认default的键
29 # print(key)
30 # print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键
31 # print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对
32 # print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value
33
34 import configparser
35 # config = configparser.ConfigParser()
36 # config.read('example.ini')
37 # config.add_section('yuan')
38 # config.remove_section('bitbucket.org')
39 # config.remove_option('topsecret.server.com',"forwardx11")
40 # config.set('topsecret.server.com','k1','11111')
41 # config.set('yuan','k2','22222')
42 #
43 # config.write(open('example.ini', "w"))
nv笔记
3.logging模块--日志模块 重要
程序执行的中间过程--需要记录下来
程序出错---日志 对内看的
给用户看的---对外看的
用法:1.简单配置 例子
参数:level,加format参数 ,detefmt,filename,filemode
--中文存在乱码,屏幕与文件不能同时展示
1 # import logging
2 # logging.basicConfig(level=logging.DEBUG) #显示DEBUG及以上的信息
3 # logging.debug('debug message') #非常细节的日志--排查错误的时候使用
4 # logging.info('info message') #正常的日志信息
5 # logging.warning('warning message')
6 # logging.error('error message') #错误
7 # logging.critical('critical message') #严重错误
8 #
9 #
10 #
11 # logger=logging.getLogger()
12 # fh=logging.FileHandler('log.log') #创造了一个能操作文件的对象fh
13 # logger.addHandler(fh)
14 #
15 # sh=logging.StreamHandler() #在screen输出
16 # logger.addHandler(sh)
17 # logger.warning('warning message')
18 #
19 # #创造一个格式
20 # format='...'
21 # sh.setFormatter(format)
22 # #logger里设置级别 设置encoding,在文件名之后
View Code
2.logger对象的方式配置
logger=logging.getLogger()
往文件中输入 写法,参数
1 # logging
2 # 日志
3 # 程序出错 -- 日志 对内看的
4 # 给用户看的 对外看的
5 import logging
6 # 简单配置
7 # logging.basicConfig(level=logging.DEBUG,
8 # format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
9 # datefmt='%a, %d %b %Y %H:%M:%S',
10 # filename='test.log',
11 # filemode='w'
12 # )
13 # logging.debug('debug message') # 非常细节的日志 —— 排查错误的时候使用
14 # logging.info('info message') # 正常的日志信息
15 # logging.warning('warning message') # 警告
16 # logging.error('error message') # 错误
17 # logging.critical('critical message') # 严重错误
18
19 # logger对象的方式配置
20 logger = logging.getLogger()
21 # 吸星大法
22
23 # 先创造一个格式
24 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
25 formatter1 = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
26
27 # 往文件中输入
28 fh = logging.FileHandler('log.log',encoding='utf-8') # 创造了一个能操作文件的对象fh
29 fh.setFormatter(formatter) # 高可定制化
30 logger.addHandler(fh)
31 logger.setLevel(logging.DEBUG)
32 sh = logging.StreamHandler()
33 sh.setFormatter(formatter1)
34 logger.addHandler(sh)
35
36 fh.setLevel(logging.ERROR)
37 sh.setLevel(logging.DEBUG)
38
39
40 logger.debug('logger debug message')
41 logger.info('logger info message')
42 logger.warning('logger warning message')
43 logger.error('程序出错了')
44 logger.critical('logger critical message')
nv笔记
五、反射!! 及面向对象进阶
!!!!!!反射 百分重要
定义:通过字符串数据类型的 变量名,来访问变量的值
1 # 什么叫反射
2 # 通过字符串数据类型的 变量名 来访问变量的值
3
4 # name = 'value'
5
6 # eval('')
7
8 # 类名 反射 静态属性
9 # 对象名 反射 对象属性 和 方法
10 # 模块 反射 模块中的名字
11 # 反射 自己所在文件中的名字
12
13 # x.y 这样的形式 都可以用反射
14
15 # print('aaa'.startswith)
16 # print('aaa'.startswith('a'))
17 # # 'startswith'
18 # ret = getattr('aaa','startswith')
19 # print(ret('a'))
引入
使用场景:
1.类名 反射 静态属性
2.对象名 反射 对象属性和方法
1 class Person:
2 role='Person'
3 def __init__(self,name):
4 self.name=name
5 def eat(self):print('eating')
6 def drink(self):print('drinking')
7 def play(self): print('playing')
8 def sleep(self): print('sleeping')
9
10 #1.类名 反射 静态属性
11 print(getattr(Person,'role')) #Person
12 #2.对象名反射属性
13 alex=Person('alex')
14 print(getattr(alex,'name')) #alex
15
16 #2.对象名反射方法
17 # while True:
18 # inp = input('>>>') #注意input在上面
19 # if hasattr(alex,inp):
20 # getattr(alex,inp)() #不加括号拿到内存地址
21 #小结:
22 # 首先 使用getattr取获取一个名字,如果在这个对象的命名空间中没有这个名字 会报错
23 # getattr的反射好伴侣 hasattr
24 # 如果使用getattr取获取一个方法,那么只能拿到这个方法的内存地址 加上括号就是执行,当然,括号里的参数可以照传不误
25 # 如果getattr获取一个属性,那么直接使用反射就可以获取到值
情景12
3.模块 反射 模块中的名字 (属性方法 类中的)
4.反射自己所在文件中的名字!!
sys.modules['__main__'] 例子
1 #3.模块 反射 模块中的名字 (属性方法 类中的)
2 # import mymodule
3 import time
4
5 # mymodule.func1()
6 # time.sleep(0.5)
7 # print(mymodule.money)
8 # getattr(mymodule,'func1')() #调用方法
9 # print(getattr(mymodule,'money')) #调用属性
10 # getattr(time,'sleep')(1) #调用sleep
11 #调用类中的
12 # Manager = getattr(mymodule,'Manager') #拿到manager
13 # a = Manager() #实例化
14 # a.eat()
15
16 # 4.反射 自己所在文件中的名字
17 value = '123'
18 def func1():
19 print('func1')
20 class Manager:
21 def eat(self):
22 print('eating')
23 import sys
24 print(sys.modules['__main__']) #取到模块
25 print(getattr(sys.modules['__main__'],'value')) #取value值
26 # print(getattr(sys.modules['__main__'],'func1'))() #反射方法
27 #反射类
28 Manager=getattr(sys.modules['__main__'],'Manager')
29 Manager().eat() #eating
情景34
1 # 模块就是一个py文件
2 # 所谓的模块导入 就是执行了这个文件而已
3 money = 100
4 def func1():
5 print('func1')
6
7 def func2():
8 print('func2')
9
10 class Manager:
11 def eat(self):
12 print('eating')
mymodule.py
x.y的形式,都可以用反射
作业例子--不同管理员执行不同的权限
1 class Manager:
2 def __init__(self,name):
3 self.name = name
4 def create_course(self):
5 pass
6 class Teacher:
7 def __init__(self,name):
8 self.name = name
9 def list_student(self):
10 pass
11 class Student:
12 def __init__(self,name):
13 self.name = name
14
15 a = Student('a')
16 a.age = 19
17 setattr(a,'age',25)
18 print(a.__dict__)
19 print(a.age)
20 import sys
21 #1.先登录 账户密码
22 #login name,pwd
23
24 id = 'Manager'
25 if hasattr(sys.modules['__main__'],id):
26 obj = getattr(sys.modules['__main__'],id)()
作业例子
isinstance和issubclass两个方法不常用
setattr设置属性--了解
delattr 删除属性--了解 obj对象
__new__方法 !非常重要 面试经常被问! Foo例子
__new__方法 构造方法,创建一个对象
__init__初始化方法
先执行new方法,object.new() 再执行init
经历过程:
# Foo() --> python解释器接收到你的python代码
# python解释器替你去做了很多操作
# 包括 主动帮助你 调用 new方法 去创造一个对象 —— 开辟内存空间 —— python语言封装了开辟内存的工作
# object的new方法里 —— 帮你创造了对象
# 调用init用到的self参数 就是new帮你创造的对象
什么叫单例模式:
设计模式--23种(赵博士以后会讲)
单例模式:某一类只有一个实例 person例子 解释孩子例子
__len__ 例子,类中的内置方法,很多都和内置函数相关!
__str__ 重要!str方法必须返回字符串类型
其它自己看看!
六、项目规范
模块就是一个py文件
所谓的模块导入 就是执行了这个文件而已
# sys.path 列表里存储了所有模块导入的路径
软件开发规范 项目名称不要用中文,不要太长
bin conf..core db log(登录信息和操作信息)..图
sys.path 在pycharm中路径不准,可在cmd中查看
所有的模块导入,都需要精确到具体的模块
from core import core2
core2.login()
当一个文件 被直接执行的时候,这个文件的__name__属性是__main__
当这个文件被当做模块导入的时候,这个文件的__name__属性是文件名
core2 maneger文件(在此文件中from)
注:不能循环引用
config目录:userinfo_path='copy path即可'
从start.py执行,,,,导入core中
settings两种写法。。。绝对路径或join那种