seven day--面向对象及模块

复习


对象
实例化过程:
组合:
super 派生prop
多态:建立一个父类,让所有传递的数据类型都继承这个父类。

学习方法: xy rz 时间
1.画知识的思维导图:思维导图一定要画!
python:基础数据类型 文件处理 函数 模块 面向对象

整理;时间分片
 1 # 面向对象
 2 # 类 实例化 对象/实例
 3 # 什么是类? 拥有相同属性和方法的一类事物
 4 # 什么是对象? 类的一个实际表现,给类中的属性填上具体的值,能够使用类中的方法
 5 # 实例化的过程中做了那些事儿?
 6     # 对象 = 类名()
 7     # 首先要创造一个对象
 8     # 被创造出来的这个对象会作为参数传递给__init__方法中的第一个参数
 9     # 调用__init__方法,传递一些初始化参数 —— 初始化方法
10     # 将初始化之后的对象返回给调用者
11 # 查看属性和调用方法
12     # 类名 : 静态属性、类属性
13     # 对象 : 调用方法(动态属性)、查看对象的属性
14 # 组合 : 两类事物之间的所有关系,什么有什么的关系
15 # 继承 :两个类之间的包含关系,什么是什么的关系
16     # 钻石继承问题
17         # 经典类 : 在一个子类中寻找方法的时候,从子类到父类先找到的名字会被执行。
18                     # 深度优先就是在经典类中找类的顺序的一种算法
19         # 新式类 : 广度优先
20         # py2中,主动继承object类的都是新式类,它的子类也是新式类
21         # py3中,所有的类都是新式类,都继承object
22     # super :
23         # 自己有父类也有的时候,在单继承中super就可以用父类的
24         # 在多继承中 super遵循mro广度优先顺序
25     # 派生 :
26         # 属性
27         # 方法
28 # 多态
29         # python中不需要程序员自己实现多态
30         # 在其他强数据类型语言的面向对象中,我要传递一个参数必须指定这个参数的数据类型
31         # 但是,往往在这个地方需要传递的不止一种类型
32         # 建立一个父类,让所有要传递的数据类型都继承这个父类,在参数指定数据类型的时候
33         # 指定父类名就可以了
34 
35 # def eat(Animal alex):pass
36 
37 
38 # 画知识的思维导图:思维导图一定要画!
39     # python :基础数据类型 文件处理 函数 模块 面向对象
40     # 函数
41         # 函数的定义 :参数和返回值
42         # 生成器函数
43         # 递归函数
44         # 内置函数
45         # 匿名函数
46     # 面向对象
47         # 基础概念
48         # 定义
49         # 三大特性 : 封装
50                     # 多态
51                     # 继承
52 
53 # 北大研究生 :
54     # 整理
55     # 时间分片
View Code

一、封装

广义的封装:把变量和函数都放在类中
狭义的封装:把一些变量或方法隐藏起来,不对外公开
公有的;
私有的:__name
例子一
 1 #例子一
 2 # class Person:
 3 #     __country='中国' #私有的静态属性
 4 #     print(__country)   #类里的代码,从定义开始就执行,会输出 中国
 5 #
 6 # #print(Person.__country)   #AttributeError: type object 'Person' has no attribute '__country'
 7 # #私有的名字 ,只能在类的内部使用,不能在类的外部使用
 8 #
 9 # print(Person._Person__country)#可以调用,但不能使用该方式。
10 # print(Person.__name)   #在类的外部不能定义一个私有变量
View Code

私有的变量:在类的内部 如果使用__变量的形式会发生变形,python会自动的为你加上_类名
例子:用户名密码--变形
 1 class Person:
 2     __country = '中国'
 3     def __init__(self,name,pwd):
 4         self.name = name
 5         self.__pwd = pwd      # 私有的对象属性
 6     def login(self):
 7         print(self.__dict__)
 8         if self.name == 'alex' and self.__pwd == 'alex3714':
 9             print('登录成功')
10 
11 alex = Person('alex','alex3714')
12 alex.login()
13 print(alex.__dict__)   #{'name': 'alex', '_Person__pwd': 'alex3714'}
14 print(alex.__pwd)
View Code

不允许调用类中的私有属性!! 例子--制造密码
# class Person:
#     def __init__(self):pass
#     def __制造密码转换(self,inp):
#         print('eating')
#     def 注册(self):
#         inp = input('pwd>>>')
#         加密之后的密码 = self.__制造密码转换(inp)
View Code

# 静态属性 、 对象属性、 方法(动态属性) 前面加上双下划綫都会变成私有的
# 私有的特点就是只能在类的内部调用,不能在类的外部使用!!
面试题 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那种
 

相关推荐