01-uuid模块
# uuid用来生成一个全局唯一的id
import uuid
print(uuid.uuid1()) # 32个长度 每一个字符有16个选择 16**32
# print(uuid.uuid2())
# uuid3和uuid5是使用传入的字符串根据指定的算法算出来的,是固定的
print(uuid.uuid3(uuid.NAMESPACE_DNS, 'zhangsan')) # 生成固定的uuid
print(uuid.uuid5(uuid.NAMESPACE_DNS, 'zhangsan')) # 生成固定的uuid
print(uuid.uuid4()) # 使用的最多
这个好像没啥用(目前作者自己还没用到)
02-使用第三方模块
# Python在查找模块的时候,在哪些路径下查找?
from flask import Flask
import sys
print(sys.path)
sys.path——>查找路径
03-使用自定义模块
# 一个模块本质上就是一个py文件
# 自己定义一个模块,其实就是自己写一个py文件
# import 04-我的模块 如果一个py文件想要当做一个模块被导入,文件名一定要遵守命名规范
# 由数字、字母下划线组成,不能以数字开头
# 导入了一个模块,就能使用这个模块里变量和函数
import my_module
# 使用 from <module_name> import * 导入这个模块里"所有"的变量和函数
# 本质是读取模块里的 __all__ 属性,看这个属性里定义了哪些变量和函数
# 如果模块里没用定义 __all__ 才会导入所有不以 _ 开头的变量和函数
from demo import *
print(my_module.a)
my_module.test()
print(my_module.add(1, 2))
# 使用from demo import * 写法,不再需要写模块名
print(m)
test()
import demo
print(demo.n)
from hello import *
print(x)
print(y)
# print(_age)
import hello
# print(hello._age)
# hello._bar()
# print(hello.x)
# import datetime
# datetime._is_leap(2000)
04-包的使用
# 可以将多个具有相似或者有关联的多个模块放到一个文件夹里,便于统一管理
# 这个文件夹,我们就可以称之为包
# python包里,会有一个 __init__.py 文件
from chat import recv_msg
from chat.send_msg import x
import json
import flask
import chat
print(recv_msg.y)
print(x)
print(chat.recv_msg.y)
05-面向过程
def add_user():
pass
def del_user():
pass
def modify_user():
pass
def query_user():
pass
def show_all():
pass
def start():
while True:
print("""---------------------------
名片管理系统 V1.0
1:添加名片
2:删除名片
3:修改名片
4:查询名片
5:显示所有名片
6:退出系统
---------------------------""")
operator = input('请输入要进行的操作(数字)')
if operator == '1':
add_user()
elif operator == '2':
del_user()
elif operator == '3':
modify_user()
elif operator == '4':
query_user()
elif operator == '5':
show_all()
elif operator == '6':
pass
else:
print('输入有误,请重新输入......')
if __name__ == '__main__':
start()
06-面向对象的基本语法
# 小明今年 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方法
s1 = Student('小明', 18, 1.75) # Student() ==> 会自动调用 __init__ 方法
s2 = Student('小美丽', 17, 1.65)
# 根据业务逻辑,让不同的对象执行不同的行为
s1.run()
s1.eat()
s2.eat()
07-self语句的使用
class Student(object):
# 这个属性直接定义在类里,是一个元组,用来规定对象可以存在的属性
__slots__ = ('name', 'age', 'city')
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 指向创建好的内存空间,填充数据
# 3. 变量 s1 也指向创建好的内存空间
s = Student('张三', 18)
print(s.name)
s.say_hello()
# 没有属性,会报错
# print(s.height)
# 直接使用等号给一个属性赋值
# 如果这个属性以前不存在,会给对象添加一个新的属性
# 动态属性
s.city = '上海' # 给对象添加了一个city属性
print(s.city)
# 如果这个属性以前存在,会修改这个属性对应的值
s.name = 'jack'
print(s.name) # jack
# Student('张三',18) 这段代码具体做了什么呢? # 1. 调用 __new__ 方法,用来申请内存空间 # 2. 调用 __init__ 方法传入参数,将 self 指向创建好的内存空间,填充数据 # 3. 变量 s1 也指向创建好的内存空间 s = Student('张三', 18)天我们要说的是面向对象的核心-----类,类能帮我们把复杂的事情变得有条理,有顺序,希望大家通过学习类能改善自己的编码风格,使代码变得更为好看,更加通俗易懂。
1.类的用法
一、什么是类
类(class),作为代码的父亲,可以说它包裹了很多有趣的函数和方法以及变量,下面我们试着简单创建一个吧。
这样就算创建了我们的第一个类了。大家可以看到这里面有一个self,其实它指的就是类aa的实例。每个类中的函数只要你不是类函数或者静态函数你都得加上这个self,当然你也可以用其他的代替这个self,只不过这是python中的写法,就好比Java 中的this。
二、类的方法
1.静态方法,类方法,普通方法
类一般常用有三种方法,即为static method(静态方法),class method(类方法)和self(普通方法)。下面我们来看看他们之间的区别吧。
从这里可以看出我们的三种方法有一个共同点,那就是既可以在实例中访问,也可以直接用类访问。不同的是,类实例访问时是不会执行init方法的,也就是没有进行初始化。如果用类直接访问,可以清楚看到它的运行轨迹。如果想在一个方法里调用其他方法则只需:实例名.方法名 或者 类名.方法名 即可。
2.安全方法,私有方法,安全变量,私有变量
安全方法一般是为了保护类的安全性,为了限制访问权限而设立的。一般只需在方法前加单下划线即可,那么私有方法怎么访问呢?和其他方法访问方法一样。
安全方法:可以在外部进行调用并且其他方法也能访问到,它允许本身的任何方法进行访问,并可在外部调用,安全属性也是;
私有方法:只能在私有方法内部调用,不能通过类名或者类的实例名来调用,所以你可以在其他方法中通过self.ww来调用或者cls.ww来调用,这样就做到了私有的功能。
三、类的特性
类的特性,相信接触过面向对象的小伙伴应该都知道,封装、继承和多态。
1.封装
讲的就是将一个功能封装到类中,这个很好理解。
2.继承
就是一个类和另一个类的主体结构一致,就好比父亲和儿子的区别,儿子继承父亲所有的特点,这使得他可以少做一些重复劳动,并且他还有自己的一套,这就叫继承,下面我们通过实例说明:
可以看出我们实现了继承,就是简单的在子类中添加了父类的名字,并且写了个spuer,用来继承父类的所有的特性。虽然父类的所有东西我们都能继承,但并不是说所有的你都能用的,比如说父类的私有方法或者私有属性:
那么如果你想要使用它们那该怎么办呢?很简单,你只需将私有方法或者属性添加到父类某个可以公开访问的类中,然后子类就能使用这些父类定义的私有方法或者属性了。
当然,除了单一继承,还有多继承,它可以继承两个类的所有属性和方法,只不过写法与其他编程语言有点不同,它的多继承就是递归继承,不能同时继承,也就是:
这样就实现了多继承,多继承可以大大简化代码量。我们可以通过一些魔法方法来获得父类的名称以及说明。
__bases__#查看类的所有父类__base__ #查看类的父类__doc__ #查看类的使用文档,在类中以三引号扩起来的部分都是文档内容
我们注意到,只需继承一个类就实现了多继承,这是因为son类之前继承过father类,所以现在你必须通过son类继承father类,后面给它初始化,如果是两个没有任何关联的类,则需要写两个类名进去,并且初始化。
3.多态
多态的应用使得类更灵活,它可以共享某个方法,给所有的类对象使用。我们来看看:
这里是通过对一个函数传一个对象,使得它拥有了类的特征功能,这也就是鸭子类型。
4.动态修改值
当一个类需要大量创建实例时,可以通过魔法方法slots来声明。这样可以减少内存消耗。但是它只是动态的修改,并没有绑定到类的实例中,而且类只能访问slots里设定的值。
可以看到访问不了值,因为没有这个属性,我们再来看看没slots的时候:
现在正常了,另外,子类的slots为它本身和父类的slots,父类只是本身。这样极大省内存,但是这样好像还不够Python,因为他的局限性,让我决定使用property。property有两种创建方式,我们来看看:
一、装饰器
直接在方法上运用装饰器,十分方便。他有设置,获取,删除三个属性,例如:
可以看到,非常简单就实现了功能,少写了很多代码哦。
二、在类中定义值为property对象的类属性
使用property函数来实现:
可以看到,这样就实现,那么现在我们写一个稍微复杂点的,可以进行交互的动态修改属性吧。
可以看到,我输入属性名和属性值,如果你想做的更好,可以给它加其他功能,比如私有方法私有属性,访问其他类。总之功能多多,需要你自己动手亲自实践。
四、总结
通过对类的解读,让大家明白了,代码的简洁美观有多重要,为了我们的程序不那么low,请学好类。
-------------------End -------------------
08-魔术方法
# 魔法方法,也叫魔术方法,是内里的特殊的一些方法
# 特点:
# 1.不需要手动调用,会在合适的时机自动调用
# 2. 这些方法,都是使用 __ 开始,使用 __ 结束
# 3. 方法名都是系统规定好的,在合适的时机自己调用
# import datetime
#
# x = datetime.datetime(2020, 2, 24, 16, 17, 45, 200)
# print(x) # __str__ 方法
# print(repr(x)) # __repr__ 方法
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 = (1, 2, 4, 5),kwargs = {'m':'good', 'n':'hehehe', 'p':'heiheihei'}
print('args={},kwargs={}'.format(args, kwargs))
p = Person('zhangsan', 18)
# 如果不做任何的修改,直接打印一个对象,是文件的 __name__.类型 内存地址
# print(p) # <__main__.Person object at 0x00000217467AEA08>
# 当打印一个对象的时候,会调用这个对象的 __str__ 或者 __repr__ 方法
# 如果两个方法都写了,选择 __str__
print(p)
# print(repr(p)) # 调用内置函数 repr 会触发对象的 __repr__ 方法
# print(p.__repr__()) # 魔法方法,一般不手动的调用
p(1, 2, 4, 5, m='good', n='hehehe', p='heiheihei') # 对象名() ==> 调用这个对象的 p.__call__() 方法
09-__eq__方法介绍
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
# print('__eq__方法被调用了,other=', other)
# if self.name == other.name and self.age == other.age:
# return True
# return False
return self.name == other.name and self.age == other.age
p1 = Person('zhangsan', 18)
p2 = Person('zhangsan', 18)
p3 = Person('zhangsan', 19)
# p1 和 p2 是同一个对象吗?
# 怎样比较两个对象是否是同一个对象?比较的是内存地址
print('0x%X' % id(p1)) # 0x20CE2A8EE88
print('0x%X' % id(p2)) # 0x20CE2A8EF08
# is 身份运算符 可以用来判断两个对象是否是同一个对象
print('p1 is p2', p1 is p2) # False
# __eq__ 如果不重写,默认比较依然是内存地址
print('p1 == p2', p1 == p2) # p1 == p2本质是调用 p1.__eq__(p2),获取这个方法的返回结果
print(p1 == p3)
# is 比较两个对象的内存地址
# == 会调用对象的 __eq__ 方法,获取这个方法的比较结果
# nums1 = [1, 2, 3]
# nums2 = [1, 2, 3]
# print(nums1 is nums2) # False
# print(nums1 == nums2) # True
10-一些demo
__all__ = ['m', 'test']
m = 'yes'
n = 100
def test():
print('我是demo模块里的test方法')
def foo():
print('我是demo模块里的foo方法')
def division(a, b):
return a / b
# __name__:当直接运行这个py文件的时候,值是__main__
# 如果这个py文件作为一个模块导入的时候,值是文件名
if __name__ == '__main__':
print('demo里的name是:', __name__)
print('测试一下division函数,结果是:', division(4, 2))
# 没有设置 __all__ 会读取除了以_开始的所有变量和函数
x = 'hello'
y = 1000
# 以一个下划线开始变量,建议只在本模块里使用,别的模块不要导入
_age = 19 # 使用from 模块名 import * 这种方式无法导入
_age += 1
def _bar():
print('我是hello里的bar函数,我只能hello文件内部使用')
del (_age, _bar, x)
a = 'hello'
def test():
print('我是my_module模块里的test函数')
def add(x, y):
return x + y
pip install <package_name> 用来下载一个第三方的模块 pip uninstall <package_name> 用来删除第三方模块 pip list 用来列出当前环境安装的模块名和版本号 pip freeze 用来列出当前环境安装的模块名和版本号 阿里云服务器 从阿里镜像下载 腾讯云服务器 从腾讯镜像下载 临时修改,只修改这一个文件的下载路径 pip install <package_name> -i <url> 从指定的地址下载包 pip freeze > file_name 将安装的模块名和版本号重定向输出到指定的文件 pip install -r file_name 读取文件里模块名和版本号并安装