后续业余时间慢慢补充学习详细内容。
Python是一种解释型语言,面向对象语言
Python的解释器分类:
CPython(官方):用c语言编写的Python解释器
pypy:python自己写的可以直接编译
Jython:解释器是java编写的,可以直接编译成java字节执行
IronPython:用.net编写的Python解释器
版本(两版本互不兼容)
2.x、3.x
$ python -V
Python 3.9.0
安装、环境变量
# 指定版本安装
$ brew install python@3.9
/usr/local/Frameworks/Python.framework/Versions/3.9/bin/python3.9
/usr/local/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/bin/python3.9
/usr/local/bin/python3.9
变量前面不需要声明类型,由等号右边的值直接赋值即可:
user_name = "张三" # 等号右边为字符串字面量
age = 18 # 等号右边为数字字面量
# 上面的变量就是一个标识符。
# 在Python中所有可以自主命名的内容都是属于标识符,比如:变量名、函数名、类名。
# 标识符循环标识符规范。
整数,长度无限制
number1 = 22222
number2 = 123_456_789
# 二进制整数,0b开头
c = 0b10
# 八进制 0o开头
d = 0o10
# 十六进制 0x开头
e = 0x10
# 格式化
a = 0.1 + 0.2 # 得到结果不精确
# 格式化
user_name = "张三"
address = '广州市'
# 三引号保留字符串中格式,"""、'''
str = """锄禾日当午,
汗滴禾下土,
谁知盘中餐,
粒粒皆辛苦。
"""
# 转义字符 \
str2 = "111\n"
# 字符串格式化
str3 = "我叫%s,今年%d岁,体重%.2f公斤"
str4 = str4%("吴磊", 12, 30.5)
name = "吴磊"
age = 12
weigth = 30.5
str5 = f"我叫{name},今年{age}岁,体重{weigth}公斤"
str1 = "我叫{},今年{}岁,身高{}"
str2 = str1.format(name, age, height)
str5_1 = "我叫{name},今年{age}岁,身高{height}"
str6 = str5_1.format(name=name, height=height, age=age)
1)变量前面不需要声明类型,由等号右边的值直接赋值即可
2)每行语句写完不需要分号 ;
3)条件分支、循环分支中的条件不需要括号(),条件后以冒号:开始
4)方法的参数需要括号,参数后以冒号开始
5)类不需要括号,以冒号开始
6)一行代码可以多行书写,以 \ 来换行编写
7)命名规范:下划线命名法、帕斯卡命名法(大驼峰命名法)
列表方法的使用。
类似json、map数据格式:
字符串、列表、元组、数字序列
交集、并集、差集
按顺序执行,先定义,后使用。
1、id函数
CPython 中 id() 函数用于获取对象的内存地址。
2、语法
id([object])
3、参数
object – 对象。
4、返回值
返回对象的内存地址。
5、使用示例: id()函数可返回对象的内存地址
student = Student("张三", 28, "123@qq.com")
print(id(student)) # 4343029712
c, d 和 2.0 地址不同,但值相等。
c = 2.0
d = 2.0
print(id(c),id(d),id(2.0))
print('c == d:',c==d)
print('c is d:',c is d)
c == d 比较的是c和d的值是否相等,c is d 则比较的是c和d内存(或id)是否一样。
2537439396824 2537439396776 2537439396800
c == d: True
c is d: False
补充:id(object)返回的是对象的“身份证号”,唯一且不变,但在不重合的生命周期里,可能会出现相同的id值。此处所说的对象应该特指复合类型的对象(如类、list等)
,对于****字符串****、整数等类型,变量的id是随值的改变而改变的。
函数的参数:函数的参数,必备参数、关键字参数、默认参数、可变参数
环境变量
导入:import os
定位:当前包 -> 内置函数 -> sys.path(环境变量)
(venv) chyzhong@chyzhong-MacBook-Pro demo11_module % python
Python 3.9.0 (default, Nov 21 2020, 14:01:50)
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello #导入模块
>>> dir(hello) #列出模块属性和方法,其中双下划线的是魔法属性(内置属性)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'add', 'say_hi']
>>>
>>> hello.__doc__
'\n多行文档注释\n'
>>> help(hello)
Help on module hello:
NAME
hello - 文档注释
FUNCTIONS
add(a, b)
两数想加方法
:param a: 第一个数字
:param b: 第二个数字
:return: 返回两个数想加的值
say_hi()
定义了一个函数
:return: 无返回值
FILE
/Users/chyzhong/temp/pythondemo/pythondemo01/demo11_module/hello.py
pypi.org
__init__.py
,那么python解释器就会将这个文件夹看做包。__init__.py
告诉了python解释器,导入这个包的时候实际要导入什么内容。在python3中,即使包下没有__init__.py
文件,import包仍然不会报错。而在python2中,包下一定要有该文件,否则import包报错。__init__.py
类就是一个模板,模板里可以包含多个函数,用于实现不同的功能,这些函数也叫做 “方法” ,类中的函数第一个参数必须是self
;
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。
每个对象中都要保存三种数据:
id:对象创建后,不能修改。获取内存地址,参考id函数。
type:标识当前对象所属类型。获取数据类型,参考type函数。
value:对象中存储的具体数据。
如果不希望被外部访问,属性的名称前面加入双划线__”,使变量变为私有变量 private,内部可以访问,外部不能访问。
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
def print_score(self):
print('%s: %s' % (self.name, self.__score))
如果需要修改私有变量或者获取私有变量,需要定义具体方法返回。
class Student(object):
...
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self, score):
self.__score = score
特殊情况:双下划线的变量 也可以外部访问,只不过不能直接访问:
# Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
liu = Student("liu",90)
liu._Student__score
严重错误:
liu = Student("liu",90)
liu.get_name()
Out[40]: 'liu'
liu.__name= 'chaung'
liu.__name
Out[42]: 'chaung'
liu.get_name()
Out[43]: 'liu'
#设置__name 的时候,虽然没有报错,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。内部原有的并没有改变。
给实例设置属性的方法是通过 self 变量设置:
class Student(object):
def __init__(self, name):
self.name = name
给类本自身设置一个属性:
class Student(object):
"""docst nameor Student"""
name = 'Student'
综合起来:
class Student(object):
# 类属性(静态属性)
name = 'Student'
__name = "私有静态属性"
def __init__(self, name):
self.name = name
定义一个类属性之后,属性归类所有,类的所有实例都可以访问
liu = Student("张三")
print(liu.name) # 张三
liu.name = 'Chuang' # 上文的分析 直接给实例绑定属性
print(liu.name) # Chuang # 实例属性优先级高于类属性,会屏蔽到类属性
del liu.name # 删除实例属性
print(liu.name) # Student 类属性还存在
# print(liu.__name) # 无法访问私有静态属性
实例属性 的名字和类属性的名字相同,实例属性将会屏蔽掉类属性
改变类属性
class Student(object):
"""docstring for Student
增加一个类属性
每创建一个实例,计数加一
"""
count = 0
def __init__(self, name):
self.name = name
# 修改类静态属性
Student.count += 1
liu = Student('liu')
print(liu.count) # 1
chuang = Student('chaung')
print(chuang.count) # 2
只允许对类的实例添加固定的属性
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
liu = Student()
liu.name = 'liu'
liu.age = 18
# liu.score = 90 # AttributeError: 'Student' object has no attribute 'score'
由于score
没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。
__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。
使用 @property 装饰器,把一个 Method 变成属性调用,如下面的代码所示
class Student(object):
"""docstring for Student"""
# getter方法,加入@property后,这个方法相当于一个属性,这个属性可以让用户进行使用,而且用户有没办法随意修改。
@property
def score(self):
return self._score
# setter方法
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer !')
if value < 0 or value > 100:
raise ValueError('score must be in 0: 100')
self._score = value
使用 @property 把 getter 方法变成属性,之后又创建了一个装饰器, @score.setter 把setter方法变成属性赋值:
liu = Student()
liu.score = 90 # 调用setter方法设置属性
print(liu.score) # 90 调用getter方法获取属性
# liu.score = 900 #ValueError: score must be in 0: 100
注意: 使用 liu.score = 90 的时候, 实际上相当于调用setter方法
使用 liu.score 相当于调用 getter方法
定义只读属性 只定义 getter 方法, 不定义 setter 方法:
class Student(object):
"""
输入出生日期,
计算年龄
但是不能直接修改年龄
"""
# birth的getter方法
@property
def birth(self):
return self._birth
# birth的setter方法
@birth.setter
def birth(self, value):
self._birth = value
# age的getter方法
@property
def age(self):
return 2015 - self._birth
liu = Student()
liu.birth = 1997 # 修改出生日期
print(liu.birth) # 1997 # 获取出生日期
print(liu.age) # 18 获取年龄
# liu.age = 16 # 修改年龄 报错 AttributeError: can't set attribute
def func1(self):
pass
def __func(self): # 私有方法
pass
通过类名调用方法,类方法中第一个参数约定俗称cls,python自动将类名传给cls。
@classmethod # 类方法
def class_func(cls):
"""
定义类方法,至少有一个cls参数
:return:
"""
pass
又如:
class DataTest(object):
day = 0
month = 0
year = 0
def __init__(self, year=0, month=0, day=0):
self.day = day
self.month = month
self.year = year
def out_date(self):
print("year :", self.year)
print("month :", self.month)
print("day :", self.day)
@classmethod
def get_date(cls, data_as_string):
# 这里第一个参数是cls, 表示调用当前的类名
year, month, day = map(int, data_as_string.split('-'))
# 调用构造函数
date1 = cls(year, month, day)
# 返回的是一个初始化后的类
return date1
# 通过类方法得到本类实例这样子等于先调用get_date()对字符串进行出来,然后才使用Data_test的构造函数初始化。
# 这样的好处就是你以后重构类的时候不必要修改构造函数,只需要额外添加你要处理的函数,然后使用装饰符 @classmethod 就可以了。
r = DataTest.get_date("2022-8-3")
r.out_date()
# --------------------------------------------------------------
# 输出
year : 2022
month : 8
day : 3
staticmethod用于修饰类中的方法,使其可以在不创建类实例的情况下调用方法,这样做的好处是执行效率比较高。(类比其实就是C++里面的静态方法)当然,也可以像一般的方法一样用实例调用该方法。
该方法一般被称为静态方法。静态方法不可以引用类中的属性或方法
,其参数列表也不需要约定的默认参数self。静态方法就是类对外部函数的封装,有助于优化代码结构和提高程序的可读性。
@staticmethod # 静态方法
def static_func():
"""
定义静态方法,无默认参数
:return:
"""
pass
Python不支持多个的參数重载构造函数。
def __init__(self, name, age): # 构造方法
self.name = name # 对象属性(普通字段)
self.__age = age # 私有对象属性(私有普通字段)
class A:
coo_name = 'Jake' # 静态变量(静态字段)
__coo_age = 20 # 私有静态变量(私有静态字段)
def __init__(self, name, age): # 普通方法(构造方法)
self.name = name # 对象属性(普通字段)
self.__age = age # 私有对象属性(私有普通字段)
def func1(self):
"""
普通方法
:return:
"""
print("普通方法")
# 调用私有方法
self.__func()
def __func(self):
"""
私有方法
:return:
"""
print("私有方法")
@property
def age(self): # 属性
return self.__age
@classmethod # 类方法
def class_func(cls):
"""
定义类方法,至少有一个cls参数
:return:
"""
print("类方法")
@staticmethod # 静态方法
def static_func():
"""
定义静态方法,无默认参数
:return:
"""
print("静态方法")
a = A("张三", 30)
print(a.name, a.age)
a.func1()
a.class_func()
a.static_func()
A.class_func() # 对象调用类方法,cls得到的是类本身.
A.static_func()
只需要调用,不需要知道内部的实现细节,数据和逻辑就被封装起来了。
Python多继承,在 python 3 中,括号没不加 object,也会默认 继承 object 类。
class C1:
pass
class C2(C1):
pass
class C3(object):
pass
class C4(C3):
pass
Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先
和广度优先
.
经典类
时,多继承情况下,会按照深度优先
方式查找新式类
时,多继承情况下,会按照广度优先
方式查找经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了更多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
class D:
def bar(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> D --> C
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()
class D(object):
def bar(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> C --> D
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()
class F1:
pass
class S1(F1):
def show(self):
print 'S1.show'
class S2(F1):
def show(self):
print 'S2.show'
# 由于在Java或C#中定义函数参数时,必须指定参数的类型
# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类
# 而实际传入的参数是:S1对象和S2对象
def Func(F1 obj):
"""Func函数需要接收一个F1类型或者F1子类的类型"""
print obj.show()
s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show
s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型
isinstance(b, Animal)
Out[55]: True
isinstance(c, Dog)
Out[56]: True
#但是,一个变量可能对应多种数据类型
isinstance(c, Dog)
Out[56]: True
isinstance(c, Animal)
Out[57]: True
# 详情查看 18.5 mac版本
$ pip install pyinstaller
注意事项:
支持mac、win(Windows建议使用Python3.6.8,3.9问题多)
配合虚拟环境打包
1.在mac系统开发(为他这个程序创建一个虚拟环境)bili
2.开放...
3.开发完毕
pip freeze > reqirements.txt
4.打开win虚拟机
5.创建虚拟机环境 bili
6.安装项目依赖
pip install -r reqirements.txt
7.安装pyinstaller
pyinstaller -F xxxx
产出:bili.exe
二
1.创建虚拟环境+项目 bili
2.开发
3.安装pyinstaller
pyinstaller -F xxxx
产出:bili.exe
# 在对应的目录执行,就在对应的目录下生成build、dist文件夹
$ pyinstaller -D demo01_hello_python.py # 编译打包(执行文件以原文件名)
$ pyinstaller -D demo01_hello_python.py -n demo01 # 编译打包(为执行文件改名字)
$ dist/demo01_hello_python # 进行可执行文件所在目录,该目录有多个文件
$ ./demo01_hello_python # 运行
# 在当前目录生成文件demo01_hello_python.spec 或 demo01.spec
# 多文件打包,对于读取文件路径没有什么问题。
# 在对应的目录执行,就在对应的目录下生成build、dist文件夹
$ pyinstaller -F demo01_hello_python.py # 编译打包(执行文件以原文件名)
$ pyinstaller -F demo01_hello_python.py -n demo01 # 编译打包(为执行文件改名字)
$ dist/demo01_hello_python # 进行可执行文件所在目录,该目录只有单个文件
$ ./demo01_hello_python # 运行
# 在当前目录生成文件demo01_hello_python.spec 或 demo01.spec
# 单文件打包,对于读取文件路径有问题,单文件执行会采用临时目录,所以问题不存在
# 可使用以下代码获取路径
import sys
import os
path = sys.argv[0] # py文件的路径,或者可执行文件路径
realpath = os.path.realpath(path)
BASE_DIR = os.path.dirname(realpath)
通过动态导入模块问题,无法找到关联模块。
import importlib
card = importlib.import_module("utils.card") # 动态导入模块
# 按照上面打包方式打包后,无法找到utils模块
# 解决办法:找到对应的 ***.spec 文件,在里面Analysis对应的hiddenimports=[]填写隐藏的模块,比如:
hiddenimports=["utils.card"]
# 然后重新编译打包
pyinstaller -F ***.spec
国内的网站,比如:网易、知乎、豆瓣都是用Python开发的。
常用的框架功能有:管理路由、支持数据库、支持MVC、支持ORM、支持模板引擎、管理会话和Cookies
https://github.com/django/django.git
1、强大的URL路由配置,Django让你可以设计出非常优雅的URL,在Django里你基本可以跟丑陋的GET参数说拜拜。
2、自助管理后台,admin interface是Django里比较吸引眼球的一项contrib,让你几乎不用写一行代码就拥有一个完整的后台管理界面。
3、采用了MTV的框架模式,即模型M、模板T和视图V。
创建的Django项目后,会自动出现一个和项目名称一模一样的文件夹,文件夹有以下文件,和项目在同一级目录下,有一个manage.py文件,方便以各种命令管理django项目
pythondemo03_django
├── manage.py # 【常用】命令行工具,以各种方式与该Django项目进行交互。django的入口(启动)文件、django项目管理文件(启动项目、创建app、数据管理等)。
└── pythondemo03_django
├── __init__.py # 空文件,标识该目录是一个Python 包。
├── settings.py #【常修改】该Django项目的设置/配置。
├── urls.py #【常修改】该Django项目的 URL 声明; 由 Django 驱动的网站"目录"。【存放路由与视图函数对应关系,路由层】
├── asgi.py #【接收网络请求,不用动】一个ASGI兼容的Web服务器的入口,以便运行你的项目。
└── wsgi.py #【接收网络请求,不用动】WSGI兼容的Web服务器的入口。
# 进入到项目根下
$ cd pythondemo03_django
# 创建模块user
$ python manage.py startapp book
pythondemo03_django
├── __pycache__
├── manage.py
├── db.sqlite3 ## django自带的小型数据库,settings.py文件配置,可改mysql,参考:11.1.5.4
├── manage.spec ##
├── templates ## 手动创建【文件夹,存放html文件,模板层】,一般不用
├── pythondemo03_django
│ ├── __init__.py
│ ├── __pycache__
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── book # 增加的app(模块/应用)
├── __init__.py
├── templates #【手动创建】文件夹,存放html文件,模板层
├── static ## 手动创建【静态文件,js、css、image、plugins】
├── admin.py #【固定,不用动】django默认自带的后台管理功能
├── apps.py #【固定,不用动】每个应用的独立标识
├── migrations #【固定,不用动】里面存放ORM针对数据库相关的记录,相当于日志
│ └── __init__.py
├── models.py #【重要】与数据库打交道的文件(ORM) 【存放与数据库相关的代码(ORM),模型层】
├── tests.py #【固定,不用动】自带的单元测试文件
└── views.py #【重要】该app对应的主体功能(函数类)【存放视图函数(核心业务逻辑),视图层】
在settings.py 中找到 INSTALLED_APPS =[]
在里面输入我们要注册的代码 :book.apps.BookConfig
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'book.apps.BookConfig', # 注册app应用
]
在urls.py文件中编写:
from book import views # 导入模块
urlpatterns = [
path('admin/', admin.site.urls), # Django默认的后台管理
# url 与 函数 对应关系
path('index/', views.index),
]
在views.py文件中写对应的视图函数
from django.shortcuts import render, HttpResponse
# request为一个请求对象,封装了用户发送过来的所有请求相关数据
def index(request):
"""
输出数据
"""
return HttpResponse("欢迎使用")
def user_list(request):
"""
渲染html页面
"""
# 1.如果配置了'DIRS': [os.path.join(BASE_DIR, 'templates')],则优先找根目录下的templates下的html
# 2.如果根目录找不到,则根据app的注册顺序,逐一去他们的templates目录中找)
return render(request, "user_list.html")
在settings.py文件里有STATIC_URL = 'static/'的静态文件路径配置,在app下建立static文件夹,再建立js、css、image、plugins文件夹,html引入静态文件:
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.css' %}" />
</head>
<body>
<h1>user_list</h1>
<!-- 第一种 -->
<!--<img src="/static/image/kaixue.png">-->
<!-- 第二种 -->
<img src="{% static '/image/kaixue.png' %}">
<script src="{% static 'js/jquery/jquery-3.6.0.min.js' %}" />
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}" />
</body>
</html>
如果后续静态文件路径修改,那么修改 STATIC_URL = ‘static/’ 配置即可。
在对应的应用目录中找到models.py 中 创建数据库表,user/models.py内容如下:
class Books(models.Model): # 创建表book_book -> appName_book,会自动生产id主键
name=models.CharField(max_length=10,verbose_name='书名') #创建书名 字段名
auth=models.CharField(max_length=5,verbose_name='作者') #创建作者 字段名
pub=models.CharField(max_length=5,verbose_name='出版社') #创建出版社 字段名
ISBN=models.IntegerField(max_length=20,verbose_name='书号') #创建书号 字段名
def __str__(self): #显示书名
return self.name
class UserInfo(models.Model): # 创建表book_userinfo -> appName_userinfo,会自动生产id主键
userName = models.CharField(max_length=10, verbose_name='用户名') # 用户名 字段名
password = models.CharField(max_length=10, verbose_name='密码') # 密码 字段名
address = models.CharField(max_length=10, default="广东", verbose_name='地址') # 地址 字段名,取默认值
age = models.IntegerField(max_length=10, null=True, blank=True) # 年龄 字段名,取默认值
修改数据库表结构,再执行如下命令即可:
cd pythondemo03_django
$ python manage.py makemigrations
$ python manage.py migrate
在admin.py文件中输入如下代码进行注册数据库,book/admin.py内容如下:
from django.contrib import admin
# Register your models here.
from book.models import Book
from book.models import UserInfo
# 注册到默认admin模块,在后台admin模块中可以进行增删改查操作
admin.site.register(Book)
admin.site.register(UserInfo)
$ python manage.py makemigrations # 执行后在根目录下生成db.sqlite3文件
System check identified some issues:
WARNINGS:
book.Book.ISBN: (fields.W122) 'max_length' is ignored when used with IntegerField.
HINT: Remove 'max_length' from field
Migrations for 'book':
book/migrations/0001_initial.py
- Create model Book
执行完成后,就会生成对应的数据库表(默认表,业务表):
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
$ pip install pyinstalle
$ pyi-makespec -D manage.py # 增加manage.spec文件
Wrote /Users/chyzhong/temp/pythondemo/pythondemo03_django/manage.spec.
Now run pyinstaller.py to build the executable.
以文本的方式打开.spec文件,spec文件格式如下。具体spec的使用,可以查看官网
https://pyinstaller.readthedocs.io/en/stable/spec-files.html
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['manage.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='manage',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='manage',
)
不修改.spec文件,直接运行以下语句
$ pyinstaller manage.spec # 在项目根目录下生成build、dist目录
有警告:
432 WARNING: Failed to collect submodules for 'django.contrib.postgres.forms' because importing 'django.contrib.postgres.forms' raised: ModuleNotFoundError: No module named 'psycopg2'
28260 WARNING: Hidden import "django.contrib.contenttypes.templatetags" not found!
28279 WARNING: Hidden import "django.contrib.staticfiles.context_processors" not found!
28280 WARNING: Hidden import "django.contrib.sessions.context_processors" not found!
28284 WARNING: Hidden import "django.contrib.contenttypes.context_processors" not found!
28289 WARNING: Hidden import "django.contrib.admin.context_processors" not found!
28290 WARNING: Hidden import "django.contrib.messages.templatetags" not found!
28296 WARNING: Hidden import "django.contrib.auth.templatetags" not found!
28307 WARNING: Hidden import "django.contrib.sessions.templatetags" not found!
28307 WARNING: Hidden import "django.contrib.staticfiles.templatetags" not found!
28803 WARNING: Hidden import "django.db.backends.__pycache__.base" not found!
28998 WARNING: Hidden import "django.db.backends.oracle.compiler" not found!
36185 WARNING: Hidden import "mx.DateTime" not found!
28275 WARNING: Hidden import "book.apps.BookConfig.context_processors" not found!
28279 WARNING: Hidden import "book.apps.BookConfig.templatetags" not found!
28296 WARNING: Hidden import "book.apps.BookConfig" not found!
------------------------------------------------------------------------------------------
423 WARNING: Failed to collect submodules for 'django.contrib.gis.utils' because importing 'django.contrib.gis.utils' raised: django.core.exceptions.ImproperlyConfigured: Could not find the GDAL library (tried "gdal", "GDAL", "gdal3.4.0", "gdal3.3.0", "gdal3.2.0", "gdal3.1.0", "gdal3.0.0", "gdal2.4.0", "gdal2.3.0", "gdal2.2.0"). Is GDAL installed? If it is, try setting GDAL_LIBRARY_PATH in your settings.
------------------------------------------------------------------------------------------
2765 WARNING: Failed to collect submodules for 'django.contrib.gis.admin' because importing 'django.contrib.gis.admin' raised: django.core.exceptions.ImproperlyConfigured: Requested setting USE_I18N, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
# 常规的pip install psycopg2 已经不能成功安装,报错:Error: pg_config executable not found.
$ brew install krb5
$ brew install postgresql # 依赖krb5,否则报错:Error: No such file or directory @ rb_sysopen - /Users/chyzhong/Library/Caches/Homebrew/downloads/c5cf98e7b92b976228f4478680764be0947b5ad82f391ae2b16a3b34b21d25e5--krb5-1.19.3.catalina.bottle.tar.gz
# 执行过程中,iproute2mac dependency: python@3.10,当前Python是3.9
# Error: No such file or directory @ rb_sysopen - /Users/chyzhong/Library/Caches/Homebrew/downloads/7645838ce9eaec5fc1c1c6a9b4e6209417325c21cb43963e33b439378dc542a9--python@3.10-3.10.4.catalina.bottle.tar.g
$ brew install python@3.10 # 会下载python3.10版本的包python@3.10--3.10.4.catalina.bottle.tar.gz
$ brew install iproute2mac
$ pip install psycopg2
$ brew install isl
$ brew install zstd
$ brew install gcc
$ brew install expat
$ brew install geos
$ brew install hdf5
$ brew install libxml2
$ brew install libdap
$ brew install libtiff
$ brew install proj
$ brew install libgeotiff libpq
$ brew install librttopo minizip libspatialite
$ brew install netcdf openblas numpy little-cms2 openjpeg fontconfig
$ brew install glib pkg-config libpthread-stubs xorgproto libxau
$ brew install libxdmcp
$ brew install libxcb libx11 libxext libxrender lzo pixman
$ brew install cairo nspr nss qt@5 poppler-qt5
$ brew install m4 libtool
$ brew install unixodbc
$ brew install webp
$ brew install xerces-c
$ brew install gdal
$ pip3 install gdal
$ cd pythondemo03_django/dist/manage
$ ./manage runserver
# 或者
$ ./manage runserver ip:port --noreload
$ cd pythondemo03_django
$ python manage.py runserver # 默认 127.0.0.1:8000
# 或者自定义ip:port
$ python manage.py runserver 127.0.0.1:8000 # 浏览器访问 http://127.0.0.1:8000/ 即可。
右键项目-> Debug As-> PyDev:Django,即可,控制台打印url,如下:
http://127.0.0.1:8000/
# 浏览器直接访问 http://127.0.0.1:8000/ 即可。
# 还提供一个管理界面 http://127.0.0.1:8000/admin
# 命令行进入到项目根目录,执行命令创建用户名/密码:admin/123456,然后登录即可:
$ python manage.py createsuperuser
System check identified some issues:
WARNINGS:
book.Books.ISBN: (fields.W122) 'max_length' is ignored when used with IntegerField.
HINT: Remove 'max_length' from field
Username (leave blank to use 'chyzhong'): admin
Email address: 123456@126.com
Password: 123456
Password (again): 123456
The password is too similar to the email address.
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
$ cd /Users/chyzhong/temp/pythondemo
# pythondemo03_django_demo02为项目名
$ django-admin startproject pythondemo03_django_demo02
# 目录结构,和11.1.1的目录结构一致,如下:
$ tree pythondemo03_django_demo02
pythondemo03_django_demo02
├── manage.py
└── pythondemo03_django_demo02
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
# 查看18.5的python3 版本使用情况
# PyCharm导入项目后,即自动使用虚拟环境,如果无法有引入,利用PyCharm进行配置。
python manage.py runserver 127.0.0.1:8000
http://127.0.0.1:8000/
views.py
def user_detail(request):
"""
渲染user_detail.html页面
"""
name = "张三"
roles = ["管理员", "CEO", "保安"]
user_info = {"name": "张三", "salary": 30000, "role": "CEO"}
# 往页面填充数据
return render(request, "user_detail.html", {"data1": name, "data2": roles, "data3": user_info})
html通过双大括号取值:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>{{data1}}</div>
<div>{{data2}}</div>
<!-- 根据数组索引取值 -->
<div>{{data2.0}}</div>
<div>{{data2.1}}</div>
<div>{{data2.2}}</div>
<!-- 循环取值 -->
<div>
{% for item in data2 %}
<span>{{item}}</span>
{% endfor %}
</div>
<hr />
<!-- 字典 -->
{{ data3 }}
<!-- 字典, 根据key获取值 -->
{{ data3.name }}
{{ data3.salary }}
{{ data3.role }}
</body>
</html>
$ pip3 install mysqlclient==2.1.1 # 定制版本
$ pip3 install mysqlclient # 最新版本
orm协助我们操作两件事情:
创建、修改、删除数据库仲的表。【不能创建数据库】
操作表中的数据。
在配置文件pythondemo03_django/settings.py里面,搜索DATABASES的配置。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
【参考】https://docs.djangoproject.com/en/4.1/ref/settings/#databases,修改ENGINE即可:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'python_demo',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
from book.models import UserInfo
# 新增
def add_userinfo(request):
UserInfo.objects.create(userName="李四", password="1234567", address="广东省广州市天河区", age=34)
return HttpResponse("成功")
# 更新 http://127.0.0.1:8000/userinfo/update_userinfo?id=5&address=zhanjiang
def update_userinfo(request):
id_param = request.GET.get("id")
address_param = request.GET.get("address")
userinfo_list = UserInfo.objects.filter(id=int(id_param))
print(type(userinfo_list)) # 类型:<class 'django.db.models.query.QuerySet'> ,数据不存在时:<class 'NoneType'>
print(userinfo_list) # <QuerySet [<UserInfo: UserInfo object (5)>]> ,数据不存在时:None
if not userinfo_list:
return HttpResponse("数据不存在")
userinfo_list.update(address=address_param)
for userinfo in userinfo_list:
print(userinfo.id, userinfo.userName, userinfo.password, userinfo.address, userinfo.age)
return HttpResponse("成功")
# 根据条件删除
def delete_userinfo(request):
UserInfo.objects.filter(id=2).delete()
return HttpResponse("成功")
# 全部删除
def delete_all_userinfo(request):
UserInfo.objects.all().delete()
return HttpResponse("成功")
# 查询全部
def list_all_userinfo(request):
userinfo_list = UserInfo.objects.all()
print(type(userinfo_list)) # 类型:<class 'django.db.models.query.QuerySet'>
print(userinfo_list) # <QuerySet [<UserInfo: UserInfo object (5)>]>
for userinfo in userinfo_list:
print(userinfo.id, userinfo.userName, userinfo.password, userinfo.address, userinfo.age)
return HttpResponse("成功")
# 过滤查询
def get_one_userinfo(request):
userinfo = UserInfo.objects.filter(id=1).first()
print(type(userinfo)) # 类型:<class 'django.db.models.query.QuerySet'> ,数据不存在时:<class 'NoneType'>
print(userinfo) # <QuerySet [<UserInfo: UserInfo object (5)>]> ,数据不存在时:None
if not userinfo:
return HttpResponse("数据不存在")
print(userinfo.id, userinfo.userName, userinfo.password, userinfo.address, userinfo.age)
return HttpResponse("成功")
https://flask.palletsprojects.com/en/2.0.x/
https://www.tornadoweb.org/en/stable/
https://bottlepy.org/docs/dev/
https://cherrypy.org/
http://falconframework.org/
https://trypyramid.com/
https://webpy.org/
https://www.turbogears.org/
https://asgineer.readthedocs.io/
https://emmett.sh/
https://github.com/dutradda/apidaora
http://www.quixote.ca/
两种方法进行数据库的连接分别是PyMySQL和mysql.connector
$ pip install PyMySQL
$ pip install mysql-connector-python
# python3 连接mysql的模块mysql-connector-python,纯python驱动器,不再依赖C语言的库,并且兼容python2和python3.
方式一:
try:
a = int(input("输入数字:")) # 捕获异常
except:
a = int(input("必须输入数字:")) # 处理异常
num = a + 10
print("{}+10={}".format(a, num))
方式二:
try:
a = int(input("输入数字:"))
except Exception as e:
print("发生了异常", e)
a = int(input("必须输入数字:"))
num = a + 10
print("{}+10={}".format(a, num))
方式三:
try:
a = int(input("输入数字:"))
except Exception as e:
print("发生了异常", e)
finally:
print("这条代码一定要执行!!")
num = a + 10
print("{}+10={}".format(a, num))
class Student(object):
"""docstring for Student"""
# getter方法
@property
def score(self):
return self._score
# setter方法
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer !') # 抛出异常
if value < 0 or value > 100:
raise ValueError('score must be in 0: 100')
self._score = value
liu = Student()
liu.score = 90
print(liu.score) # 90
# liu.score = 900 #ValueError: score must be in 0: 100
class MineException(Exception):
def __init__(self, msg):
Exception.__init__(self, msg)
def User(username, password):
if username is None or username.stript() == "":
raise MineException("用户名不能为空!")
if password is None or password.stript() == "":
raise MineException("密码名不能为空!")
if __name__ == '__main__':
try:
User(None, None)
except Exception as e:
print("抛出异常---》", e)
过程:源码->编译->字节码->虚拟机
├── demo01
│ ├── __init__.py
│ └── demo01.py
├── demo02
│ ├── __init__.py
│ └── demo02.py
└── main.py
demo01.py
def func():
print("hello python")
demo02.py
from demo01.demo01 import func
func()
运行demo02.py后:
├── demo01
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc # __init__.py文件的编译文件
│ │ └── demo01.cpython-39.pyc # demo01.py文件的编译文件 格式是<module>.<interpreter-version>.pyc
│ └── demo01.py
├── demo02
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc # __init__.py文件的编译文件
│ │ └── demo02.cpython-39.pyc # demo01.py文件的编译文件,字节码文件
│ └── demo02.py
├── demo03
│ ├── __init__.py
│ └── demo03.py
└── main.py
__pycache__
一般都是当前包下有模块被import之后,生成的__pycache__
文件夹,里面会对被import的模块进行编译,还有包默认的__init__.py
都会被编译成pyc文件,待到下次运行时不需要编译,而是直接运行pyc文件(前提是源文件没有更新过)。
Python在下一次执行时,会检查源代码文件(*.py)文件与字节码文件(*.pyc)的时间戳,如果时间戳一致,说明源代码没有修改,那么就会跳过对源代码的编译过程而直接加载字节码进入虚拟机执行。如果时间戳不一致,才会重新编译。而字节码的执行相对较快,这样就大大缩短了项目运行前的准备时间。
注意
:对于被导入的module才会生成对应的*.pyc文件,所以demo03.py并没有生产对应的pyc文件。即:字节码只针对哪些被导入(import)的文件而生成,而不是顶层的执行脚本。
pip 是 Python 包管理工具(管理第三方库),该工具提供了对Python 包的查找、下载、安装和卸载的功能,现在用到的所有包不是自带的就是通过pip安装的。Python 2.7.9 + 或 Python 3.4+ 以上版本都自带 pip 工具。
安装包模块,也可以借助pycharm来对相应的项目进行安装。
# 如果没有pip命令,则安装或更新
$ python3.9 -m pip install --upgrade pip
$ python -m pip install --upgrade pip
$ pip --version
pip 20.3.4 from /Library/Python/2.7/site-packages/pip (python 2.7)
pip 22.2.2 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)
# pip转移到Python3.9
$ curl https://bootstrap.pypa.io/get-pip.py | python3
# 查看版本,也可以查询到安装到对应的目录
$ pip -V
pip 22.2.1 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)
$ pip list
Package Version
---------------------- -------
lxml 4.9.1
mysql-connector-python 8.0.30
mysqlclient 2.1.1
pip 22.2.1
protobuf 3.20.1
PyMySQL 1.0.2
setuptools 50.3.2
wheel 0.35.1
# 如果查看某个模块信息,命令如下:
$ pip show xx
# 安装lxml模块
$ pip install lxml -i https://pypi.douban.com/simple
$ pip3 install PyMySQL
$ pip show PyMySQL
Name: PyMySQL
Version: 1.0.2
Summary: Pure Python MySQL Driver
Home-page: https://github.com/PyMySQL/PyMySQL/
Author: yutaka.matsubara
Author-email: yutaka.matsubara@gmail.com
License: "MIT"
Location: /usr/local/lib/python3.9/site-packages
Requires:
Required-by:
$ pip3 install mysqlclient==2.1.1
$ pip3 install mysqlclient
# 如果上面报错,如下:
# OSError: mysql_config not found
#就确认一下mysql的环境变量
# export PATH=${PATH}:/usr/local/mysql/bin
$ pip show mysqlclient
Name: mysqlclient
Version: 2.1.1
Summary: Python interface to MySQL
Home-page: https://github.com/PyMySQL/mysqlclient
Author: Inada Naoki
Author-email: songofacandy@gmail.com
License: GPL
Location: /usr/local/lib/python3.9/site-packages
Requires:
Required-by:
# 手动下载安装包 https://pypi.org/project/mysqlclient/#files
$ pip install mysql
pip install mysql-connector-python
# https://pypi.org/project/MySQL-python/
pip install MySQL-python # ModuleNotFoundError: No module named 'ConfigParser'
# 原因:在 Python 3.x 版本后,ConfigParser.py 已经更名为 configparser.py 所以出错!Mac系统目前没有区分大小写:
cd /usr/local/Cellar/python@3.9/3.9.0_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/
cp configparser.py ConfigParser.py
# 使用venv来创建python虚拟环境。
# venv只支持python3,python3 以下的版本Virtualenv,使用方法与venv大致相同。
# python3以下 版本
$ pip install virtualenv
$ virtualenv --version
# 进入项目根目录下
# 创建Python虚拟环境,只有一个参数就是虚拟环境的名字一般默认为venv即可
$ virtualenv venv
# 虚拟环境创建好了需要激活才可以使用,使用如下命令激活虚拟环境
virtualenv Scripts\activate
# python3 版本,进入项目根目录下
#############################Linux/Mac######################
# 创建虚拟环境 venv
$ python -m venv venv
$ cd venv
$ # 激活虚拟环境
$ source bin/activate
(venv) chyzhong@chyzhong-MacBook-Pro venv $
# 关闭/退出虚拟环境
(venv) chyzhong@chyzhong-MacBook-Pro venv $ deactivate
#############################Windows########################
# 创建虚拟环境 venv
$ python -m venv venv
$ cd MYvenv # 进入MYvenv虚拟环境
$ cd Scripts # Scripts目录
$ activate # 运行activate激活虚拟环境
(venv) chyzhong@chyzhong-MacBook-Pro venv $
#############################################################
# 创建虚拟环境之后,venv下会有一个pyvenv.cfg文件,该文件的内容为:
home = /usr/local/opt/python@3.9/bin
include-system-site-packages = false
version = 3.9.12
# 将include-system-site-packages值改为true可以把主环境的依赖导入到虚拟环境中。
pip3 install django
django-admin --version # 4.1 如果报错,需要检查环境变量
pip install pyinstaller
pip install psycopg2
pip install requests
pip install cmdb
安装谷歌浏览器扩展程序 chrome_Xpath_v2.0.2.crx.zip
关闭浏览器
重新打开浏览器,打开一个网页
command + Shift + X 出现小黑框即可
//:查找所有子孙节点,不考虑层级关系
/ :找直接子节点
//div[@id]
//div[@id="maincontent"]
//@class
//div[contains(@id,"he")]
//div[starts-with(@id,"he")]
//div/h1/text()
//div[@id="head" and @class="s_down"]
//titile | //price
机器学习基础知识:
KNN算法
线性回归
逻辑斯蒂回归算法
决策树算法
朴素贝叶斯算法
支持向量机
聚类k-means算法