又开始的python-day07-20200731-uuid-pip-自定义模块-包-面向对象-魔法方法-is

# P144
# uuid 模块
# 用来生成一个全局唯一的id模块
import uuid
# print(uuid.uuid1()) # 32个长度 每隔字符有16个选择 16 ** 32 分之一  # 可以保证全球唯一
# 基于mac地址 时间戳 随机数 生成的唯一uuid
# print(uuid.uuid2())
# uuid3 uuid5 是使用传入的字符串根据指定的算法算出来的固定的uuid 二者就是算法不一样 
# print(uuid.uuid3(uuid.NAMESPACE_DNS,'zss')) # 生成固定的uuid
# print(uuid.uuid5(uuid.NAMESPACE_DNS,'zss')) # 生成固定的uuid 
# print(uuid.uuid4()) # 使用的最多 伪随机数得到uuid 有一定概率重复 但很低
# 应用场景 注册的时候确认邮箱 可以根据uuid确认 那个是哪个


# pip命令的使用
# 管理资源包的第三方工具
# pip install flask
# pip install
# 安装flask包 然后就可以导入第三方模块使用
# pip uninstall flask
# pip uninstall 
# 卸载 删除
# pip list
# 列出当前环境安装模块
# pip freeze
# 列出当前环境安装的模块名和版本号
# pip freeze > file_name  
# 将安装的模块名和版本号重定向输出到指定文件 习惯性名字 requirements.txt
# 在一台服务器开发 想要换一台的时候 可以这样
# pip install -r file_name
# 读取文件里的模块名和版本号并安装
# pip isntall flask -i https://pypi.douban.com/simple/
# 下载的时候指定国内的平台 下载 快很多 默认是国外的地址 临时修改
# 当前用户下 创建一个pip的文件夹 在到里面创建一个pip.ini的文件 里面内容是
# [global]
# index-url=https://pypi.douban.com/simple/
# [install]
# trusted-host=pypi.douban.com
# 不带#号 永久更改下载地址
from flask import Flask
# P146



# 使用自定义模块
# 一个模块本质上就是一个py文件
# 自己定义一个模块其实就是自己写一个py文件
# 但模块的命名要符合命名规范 数字 字母下划线组成 但不能以字母开头
# 导入了一个模块 就能使用这个模块里的变量和函数
# import my_module
# my_module.test()

# 导入模块里所有的变量和函数
# 本质是读取模块里的__all__属性 看这个属性定义了哪些变量和函数
# 如果模块没有定义__all__ 才会导入所有不以_开头的变量和函数
# 以下划线_ 开头的变量就无法使用 而且这种变量不建议调用 私有 建议只在本模块使用
# _ 开头的变量 方法 统一默认不给别人使用
# 但只限于这种语法
# from demo import * # 这种写法在调用的时候不需要写模块名
# print(m)
# test()

# 如果自己的模块有些方法不让别人使用 就最后用del删除掉
x = '11'
# y = 100
_age = 19
def _bar():
	print('只自己本模块使用')


del (_age,_bar)



# __name__ 的使用
import hello # 导入模块 首先会把导入的模块执行一次
# 但有时候会有测试信息不用执行的时候 可以用__name__ 去定义
print(hello.x)

# __name__ 当直接运行这个py的文件的时候 值是__main__
# 如果这个py文件作为一个模块导入的时候 值是文件名
# if __name__ == '__main__':
	# print('测试') # 保证这段代码是直接运行才会执行的
	


# 包的使用
# 可以将多个具有相识或者关联的多个模块放到一个文件夹里 便于统一管理
# 这个文件夹称之为包
# python 包里 会有一个__init__.py 文件
# __init__.py 这个里面东西很多
# 文件夹chat 下创建 recv_msg.py send_msg.py
# from 后面的就是包  有时候是模块有时候是包
# 了解 一般不用 只是会用包
from chat import recv_msg
from chat.send_msg import y
# 都可以导入
print(recv_msg.x)
print(y)



# 面向对象的介绍
# 面向过程:根据业务逻辑从上到下写代码
# 面向对象:将变量与函数绑定到一起,分类进行封装,每隔程序只要负责分配给自己的分类,这样能够更快速的开发程序,减少了代码的重复
# 名片管理系统 就是一个面向过程的写法 关注点 在于 怎么做
# 面向对象编程的关注点 在于 谁来做
# 通过类创建对象
# 类就是对一群具有相同特征或者行为的事物的一个统称,是抽象的
# 特征其实就是一个变量 在类里我们称之为属性
# 行为其实就是一个函数 在类里我们称之为方法
# 类其实就是由 属性和方法组成的一个抽象概念
# 类就相当于制造飞机的图纸 规定了飞机的某些特征 和 行为 并不是一个具体的飞机 而是对飞机的一个抽象额概念 出现的目的是为了让我们创建飞机
# 类 三要素: 类名 属性 方法      也就是名字 特征 行为 
# 对象是由类创建出来的一个具体的存在 可以直接使用


# 面向对象的基本语法
# 小明 18 身高 1.75 每天早上跑完步 会去吃东西
# 小美 17 身高 1.65 不跑步 喜欢吃东西

# 定义类 :类名怎么定义 使用class 来定义一个类
# class 类名 : 类名一般遵守大驼峰命名法 每一个单词的首字母都大写
# 1. class 类名:
# 2. class 类名(object):
class Student(object): # 关注这个类有哪些特征和行为
	# 在__init__ 方法里 以参数的形式定义特征 我们称之为属性
	def __init__(self,name,age,height): 
		self.name = name
		self.age = age
		self.height = height
	def run(self):
		print('在跑步')
	def eat(self):
		print('在吃东西')
# 使用Student 类创建两个实例对象 s1 s2
# s1 和 s2 都会有name age height 属性 同时都有 run eat 方法
# Student() 会自动调用__init__方法
s1 = Student('小明',18,175)
s2 = Student('小美',17,165)

# 根据业务逻辑 让不同的对象执行不同的行为
print(s1.name,s1.age,s1.height)
s1.eat()



# self语句的使用
# __slots__

class Student(object): # 关注这个类有哪些特征和行为
	# 在__init__ 方法里 以参数的形式定义特征 我们称之为属性
	__slots__ = ('name','age','height')
	# 这个属性直接定义在类里 是一个元组 用来规定对象可以存的属性 只有定义了才可以用
	def __init__(self,x,y): 
		self.name = x
		self.age = y
	def say_hello(self):
		print('大家好我是',self.name)
# Student('张三',18) 这段代码具体做了什么
# 1.调用 __new__ 方法 申请一段内存空间
# 2.调用 __init__ 方法 并让self指向申请好的内存空间 填充数据 里面 name:张三 age:18
# 3.让s1 也指向创建好的内存空间
s1 = Student('张三',18)
print(s1.name)
s1.say_hello()

# 没有属性会报错
# print(s1.height)

# 直接用等号给一个属性赋值
# 如果这个属性之前不存在 会给对象添加一个新的属性
# 动态属性
s1.height = 175
print(s1.height)


# 魔法方法 也叫魔术方法 是类里的特殊的一些方法
# 特点:1.不需要手动调用 会在合适的时机自动调用
# 		2.这些方法 都是以__ 开始 __ 结束的
# 		3.方法名都是系统规定好的
class Person(object):
	def __init__(self,name,age):
		print('__init__被调用了')
		self.name = name
		self.age = age
	# def __del__(self):
		# 当对象被销毁时 会自动调用
		# print('__del__被调用了')
	def __repr__(self): # 结果更加在意正确性
		return 'hello'
	def __str__(self): # 结果更加在意可读性
		return '姓名:{},年龄:{}'.format(self.name,self.age)
	def __call__(self,*args,**kwargs):
		print('__call__被调用了')
		# args 元组
		# kwargs 字典
		print('args={},kwargs={}'.format(args,kwargs))
		fn = kwargs['fn']
		return fn(args[0],args[1])
		
p = Person('zss',18)
# 创建对象的时候会自动调用__init__方法
# 程序结束的时候 会调用__del__
print(p) # <__main__.Person object at 0x030C6310>
# 如果不做修改 直接打印一个对象 是文件的模块名 类型 内存地址
# 当打印对象的时候 会调用对象的__str__ 或者 __repr__ 方法 的结果 2个都有的话只调用str的

# 魔法方法也可以手动调用 但一般不手动
print(repr(p))
print(p.__str__())

import datetime
x = datetime.datetime(2020,7,31,17,50,25)
print(x) # __str__  2020-07-31 17:50:25 可读性
print(repr(x)) # __repr__  datetime.datetime(2020, 7, 31, 17, 50, 25) 正确性
# 一般用str 就行了 都可以
s = p(1,2,fn=lambda x,y:x + y) # 会调用对象的__call__方法 如果没写call方法的话 会报错
# args=(1, 2),kwargs={'fn': <function <lambda> at 0x038B07C8>}
print(s)

class Persons(object):
	def __init__(self,name,age):
		# print('__init__被调用了')
		self.name = name
		self.age = age
	def __eq__(self,other):
		print('__eq__被调用了',other)
		return self.name == other.name and self.age == other.age
p1 = Persons('张三',18)
p2 = Persons('张三',18)
# p1 p2 不是同一个对象 内存地址不一样
# 怎么比较 看内存地址
print('0x%X' % id(p1))
print('0x%X' % id(p2))

# is 身份运算符 判断2个对象是否是同一个对象
print(p1 is p2) # False
print(p1 == p2) # False
nums1 = [1,2,3]
nums2 = [1,2,3]
print(nums1 is nums2) # False is 比较2个对象的内存地址
print(nums1 == nums2) # True == 会调用__eq__方法 没有返回值就是none
# P155
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值