LXC的Python学习笔记

python3

基本数据类型

Number : 数字
整数(int)、小数、浮点数(float)
其他语言:单精度(float),双精度(double)
其他语言:short,int,long

单斜杠 除法 float
双斜杠 整除 只会保留整数部分 int (1//2得到0)
10进制:满10进1(0,1,2,。。。。。9,10)
2进制:满2进1(0,1,10)前面加上0b表示2进制
8进制:满8进1,(0,1,2,。。。。7,10 前面加上0o表示8进制
16进制:满16进1 (0,1,2,。。。。9,A,B,C,D,E,F)前面加上0x

type的功能是查看某一个python变量的类型

各进制之间的转换 :

10进制转换为2进制 bin(10)
8进制转换为2进制 bin(0o7)
16进制转换为2进制 bin(0xE)

2进制转换为10进制 int(0b111)
8进制转换为10进制 int(0o77)

10进制转换为16进制 hex(888)
8进制转换为16进制 hex(0o7777)

2进制转换为8进制 oct(0b111)

转换为2 bin ; 转换为10 int ; 转换为16 hex ; 转换为8 oct

bool布尔类型:

表示真、假
bool(0)、bool("")、bool([]) 空的列表、bool({})空的元组、bool(None) 表示False ;非空表示true
complex复数(少)
复数的表示:后面加j

字符串string

用英文的单引号、双引号、三引号表示字符串

注:字符串要成对出现
1表示int ;‘1’表示string

函数print() 在这个函数里\n表示换行才会生效; idle里不会生效
字符串换行:在一行的最后加上斜杠 上下用引号引起来

转义字符:特殊的字符

1.无法‘看见’的字符;2.与语言本身语法有冲突的字符;
\n 换行
’ 单引号
\t 横向制表符
\r 回车
\n:如果文件夹是以n开头的,一般会按照\n来处理。
解决办法:在反斜杠前面再加一个反斜杠或者在字符串前面加一个r。
字符串前面加一个r后就不是一个普通字符串了,而是一个原始字符串。

字符串的基本操作方法:

字符串拼接:两个字符串合并为一个字符串

>>> "hello"+"world"
'helloworld'

字符串乘以一个常数:

>>> "hello world"*3
'hello worldhello worldhello world'

如何获得字符串里得单个字符:

>>> "hello world"[0]
'h'
>>> "hello world"[6]
'w'
>>> "hello world"[-3]
'r' 

注:序号是从0开始的,序号只有正的。空格也算一个。
[-n]在字符串截取的意义是从字符串的末尾往前数n次得到的字符
切片:字符串里面获得一组字符:[0:n],其中n表示要截取的字符的下一位(包左不包右)。

["新月打击","新","月","打","击"][-3:-1]
输出:
['月', '打']

如:“hello world”[0:4]输出hell ;“hello world”[0:5]输出hello。
“hello world”[0:-1]输出’hello worl’,这里的负数表示的是一个步长的概念。
从"hello world"里截取world:
法一:“hello world”[6:11] [6:20]也可以得到;

说明如果输入的数字大于字符串总体的长度,会按最大最后一位来取。
法二:“hello world”[6:] 冒号后面什么都不用输 默认截取到末尾。
“hello python java c# javascript php ruby”[-4:]输出ruby
负数在冒号前面的意义表示从这个字符串的末尾开始倒着数第几个字符并且把它截取出来。

列表(list)的定义:[]

type([1,2,3,4,5,6])
<class 'list'>
type(["hello","world",1,9])
<class 'list'>
type([[1,2],[3,4],[True,False]])
<class 'list'>  

二维数组:列表里面可以再嵌套列表。
列表的基本操作:

  • 列表和列表可以做加法不可以做减法和乘法,但是列表可以乘一个数字。

元组(tuple)用()表示,每一个元素之间用逗号分隔开。

  • 元组和元组可以做加法不可以做减法和乘法,但是元组可以乘一个数字。
type((1,2,3))#元组
tuple
type(1)#整型
int
type([1,2,3])#列表
list
type('hello')#字符串
str
>>> type(())
<class 'tuple'>
>>> type((1))
<class 'int'>
>>> type((1,))
<class 'tuple'>
>>> type(1)
<class 'int'>
总结:

int,float,list,bool,list,str,tuple(序列)

>>> "hello world"[0:8:3] (3表示步长,隔三个取一个)
'hlw'
>>> "hello world"[0:8:2]2表示步长,隔两个取一个)
'hlow'

判断3和7是否在序列里面

>>> 3 in [1,2,3,4,5,6]
True
>>> 7 in [1,2,3,4,5,6]
False
>>> 3 not in [1,2,3,4,5,6]
False

判断长度length len()

>>> len([1,2,3,4,5,6])
6
>>> len("wangchangcheng")
14

判断大小

>>> max([1,4,2,3,5,8])
8
>>> min(1,3,4,2,5,3,2)
1

按照本字符在ascii码表中对应的数值进行比较

>>> max('wangchangcheng')
'w'
>>> min('wangchangcheng')
'a'
>>> max('wang chang cheng')
'w'
>>> min('wang chang cheng')
' '
>>> min('wangchangchengW')
'W'

找本字符在ascii码表中对应的数值

>>> ord('w')
119
>>> ord(' ')
32
>>> ord('d')
100

集合set 无序

集合的定义:{}

集合的第一个特性:不支持获得单个字符串;不支持切片操作。

>>> type({1,2,3,4,5,6})
<class 'set'>
>>> {1,2,3,4,5,6}[0]
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    {1,2,3,4,5,6}[0]
TypeError: 'set' object is not subscriptable
    >>> {1,2,3,4,5,6}[0:2]
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    {1,2,3,4,5,6}[0:2]
TypeError: 'set' object is not subscriptable

集合的第二个特性:不重复

>>> {1,1,2,2,3,3,4,4}
{1, 2, 3, 4}

集合支持长度;可以判断一个集合是否包含某个元素

>>> len({1,2,3})
3
>>> 1 in {1,2,3}
True
>>> 1 not in {1,2,3}
False

集合求差集-可以进行减法(求两个集合的差集)

>>> {1,2,3,4,5,6}-{3,4}
{1, 2, 5, 6}

集合求交集&

>>> {1,2,3,4,5,6}&{3,4}
{3, 4}

集合求合集(并集)|

>>> {1,2,3,4,5,6} | {3,4,7}
{1, 2, 3, 4, 5, 6, 7}

定义空的集合

>>> type(set())
<class 'set'>
字典 dict { }

基本定义方式:{key1:value1,key2:value2…}

>>> {key1:value1,key2:value2,...}

很多个key和value,集合类型(set),无序,不是序列

字典和set的相似:用{}把所有的元素包括起来;不同元素之间用逗号隔开

字典和set的区别:每一个元素的定义方式不一样;set只有一个value值没有key;字典除了有value还有key;key和value之间用冒号分割开。

字典不是序列,每一个元素没有下标标识,无序

>>> {'Q':'新月打击','W':'苍白之瀑','E':'月之降临','R':'月神冲刺'}[0]#无序
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    {'Q':'新月打击','W':'苍白之瀑','E':'月之降临','R':'月神冲刺'}[0]
KeyError: 0

字典最常用、最重要的操作:通过key得到/访问vlaue

>>> {'Q':'新月打击','W':'苍白之瀑','E':'月之降临','R':'月神冲刺'}['Q']
'新月打击'
>>> {'Q':'新月打击','W':'苍白之瀑','E':'月之降临','R':'月神冲刺'}['R']
'月神冲刺'

字典里不可以有相同的key

>>> {'Q':'新月打击','Q':'苍白之瀑','E':'月之降临','R':'月神冲刺'}['Q']
'苍白之瀑'
>>> {'Q':'新月打击','Q':'苍白之瀑','E':'月之降临','R':'月神冲刺'}
{'Q': '苍白之瀑', 'E': '月之降临', 'R': '月神冲刺'}

字典的键可以是字符串也可以是数字

>>> {1:'新月打击','1':'苍白之瀑','E':'月之降临','R':'月神冲刺'}
{1: '新月打击', '1': '苍白之瀑', 'E': '月之降临', 'R': '月神冲刺'}

数字1和字符串’1’可以被识别为两个不同的key

value类型没有限制

value:str int float list set dict

>>> value:str int float list set dict
SyntaxError: invalid syntax
>>> type({1:'新月打击','1':'苍白之瀑','E':{1:1},'R':'月神冲刺'})
<class 'dict'>

key:必须是不可变的类型

(列表不可以,元组可以???)列表里的值可变,元组里的值不可变

>>> {[1,2]:'新月打击','1':'苍白之瀑','E':'月之降临','R':'月神冲刺'}
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    {[1,2]:'新月打击','1':'苍白之瀑','E':'月之降临','R':'月神冲刺'}
TypeError: unhashable type: 'list'
>>> {(1,2):'新月打击','1':'苍白之瀑','E':'月之降临','R':'月神冲刺'}
{(1, 2): '新月打击', '1': '苍白之瀑', 'E': '月之降临', 'R': '月神冲刺'}

空的字典如何定义??? a = {}

Python基本数据类型

数字(Number):
整型 int ; 浮点型float ; 布尔型bool ; 复数complex
组:
序列:字符串 str 不可变 ; 列表 list ; 元组 tuple (有序,可用下标索引来访问,切片操作[0:5])
集合(set):无序,没有索引,不能切片
字典(dict): key:value键值对是其最基本的概念

变量

A [1,2,3,4,5,6] B [1,2,3] 先把A乘3,然后再加上B,最后再加上列表A

>>> [1,2,3,4,5,6]*3+[1,2,3]+[1,2,3,4,5,6]
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 1, 2, 3, 4, 5, 6]

变量:名字,keyibi

>>> A=[1,2,3,4,5,6]
>>> print(A)
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> B=[1,2,3]
>>> A*3+B+A
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 1, 2, 3, 4, 5, 6]

其中 = 叫做赋值符号。

命名可读性要强:可以用很简单简洁的英文单词来表示一个变量。

变量的命名规则:

只能使用字母、数字、下划线任意组合且首字符不能是数字。区分大小写

系统保留的关键字不能够用在变量名中,如and、if、import 保留关键字

>>> and=1
SyntaxError: invalid syntax
>>> if=1
SyntaxError: invalid syntax
>>> import=3
SyntaxError: invalid syntax

动态语言:变量的类型不固定

>>> a=1
>>> b=a
>>> a=3
>>> print(b)
1

>>> a=[1,2,3,4,5,]
>>> b=a
>>> a[0]='1'#也可以写成[1,2,3,4,5][0]
>>> print(a)
['1', 2, 3, 4, 5]
>>> print(b)
['1', 2, 3, 4, 5]

int 、str、 tuple(不可改变)值类型 ; list、set、dict (可变)引用类型

引用类型本身的数值是可以改变的;值类型不可变

>>> a='hello'
>>> a=a+'python'
>>> print(a)
hellopython
>>> b='hello'
>>> id(b)
2305833861488
>>> b=b+'python'
>>> id(b)
2305833451568
>>> 'python'[0]
'p'
>>> 'python'[0]='o'
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    'python'[0]='o'
TypeError: 'str' object does not support item assignment
列表的可变与元组的不可变:
>>> a=[1,2,3]
>>> id(a)
3142422006336
>>> hex(id(a))
'0x2dba6f28a40'
>>> a[0]='1'
>>> id(a)
3142422006336
>>> a=(1,2,3)
>>> a[0]='1'
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    a[0]='1'
TypeError: 'tuple' object does not support item assignment

注:元组不可变,列表可变。

列表可追加可修改元素:

>>> b=[1,2,3]
>>> b.append(4)
>>> print(b)
[1, 2, 3, 4]

元组不可追加修改元素:

>>> c=(1,2,3)
>>> c.append(4)
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    c.append(4)
AttributeError: 'tuple' object has no attribute 'append'

注: b.append()表示追加一个元素

多维元组

>>> a=(1,2,3,[1,2,4])
>>> a[2]#访问3
3
>>> a[3]
[1, 2, 4]
>>> a[3][2]#访问4
4
>>> a=(1,2,3,[1,2,['a','b','c']])
>>> a[3][2][1]
'b'#访问'b'

修改元组里的元素

>>> a=(1,2,3,[1,2,4])
>>> a[1]=5
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    a[1]=5
TypeError: 'tuple' object does not support item assignment
>>> a[3][2]='4'
>>> print(a)
(1, 2, 3, [1, 2, '4'])

改变的是列表,并不是元组

运算符号:

算数运算符:+ - * / // % **

>>> [1,2,3]*3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 3-1
2
>>> 1+2
3
>>> 3/2
1.5
>>> 3//2
1
>>> 5%2   #百分号为求余数
1
>>> 2**2  #2的平方
4
>>> 2**5  #2的5次方
32

注:单斜杠为除法;双斜杠为整除;百分号为求余数

赋值运算符:= += *= /= %= **= //=

c++(c=c+1)自增运算符 c-- (c=c-1)自减运算符

>>> c=1    #把1赋值给一个变量c
>>> c=c+1 可简写成c+=1(会改变c的值)
>>> print(c)
2
>>> b=2
>>> a=3
>>> b+=a
>>> print(b)
5

比较(关系)运算符:== ! = > < >= <=

==比较两组数据类型是否相等

bool类型是关系运算符一个重要的应用

1>=1表示1是否大于或者等于1

>>> 1==1
True
>>> 1>1
False
>>> 1>=1
True

! =(不等号)

>>> a=1
>>> b=2
>>> a!=b
True
>>> b=1
>>> b+=b>=1#bool类型中,当bool类型与整型做运算时,False值为0,True为1
>>> print(b)
2

不只是数字才能做比较运算:

>>> 'abc'<'abd'
True
>>> ord('abc')
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    ord('abc')
TypeError: ord() expected a character, but string of length 3 found

字符串里有多个元素的时候的比较规则:把字符串里的每一个字符拿出来单独做比较。

如:‘abc’<‘abd’ a与a作比较,相等比较不出来,然后b与b做比较,相等比较不出来,最后比较c与d则可判断出大小。

列表也可以做关系运算:

>>> [1,2,3]<[2,3,4]
True
>>> (1,2,3)<(1,3,2)
True

逻辑运算符:and or not

主要用来操作bool类型,同时它的返回结果也是bool类型。

and(且) 所有的都是True返回的是True,有一个False返回的是False。

>>> True and True
True
>>> True and False
False

or(或) 只要有一个True都会返回True

>>> True or False
True
>>> False or False
False

not(非)只针对一个变量

>>> not True
False
>>> not False
True
>>> not not True
True

注:True False第一个字母要大写

int float 0被认为是False, 非0 被认为是True

>>> not 0.1
False

字符串:空字符串被认为是False,否则被认为是True

同理,列表、元组(tuple)、set、dict 空的被认为是False,否则被认为是True

>>> not ''
True
>>> not '0'
False
>>> not[]
True
>>> not [1,2]
False

成员运算符:in not in

用来判断一个元素是否在另外一组元素里;成员运算符的返回值是bool类型。

>>> a=1
>>> a in [1,2,3,4,5]
True
>>> b=6
>>> b in[1,2,3,4,5]
False
>>> b not in [1,2,3,4,5]
True

字典的成员运算符是针对key:value中的key

>>> b='a'
>>> b in {'c':1}
False
>>> b=1
>>> b in {'c':1}
False
>>> b='c'
>>> b in {'c':1}
True

身份运算符:is is not

身份运算符返回结果是bool值

>>> a=1
>>> b=2
>>> a is b
False
>>> a=1
>>> b=1
>>> a is b
True
>>> a='hello'
>>> b='world'
>>> a is b
False
>>> c='hello'
>>> a is c
True

如果两个变量的取值相等,则is 返回True,

is和 ==的区别,关系运算符( ==)所比较的是两个变量的 ;is不是比较值相等,而是比较两个变量的身份(内存地址)是否相等。

>>> a=1
>>> b=2
>>> a==b
False
>>> a=1
>>> b=1
>>> a is b
True
>>> a==b
True
>>> a=1
>>> b=1.0
>>> a==b
True
>>> a is b
False

is是身份运算符,两个变量取值相同并不等于身份相同

>>> id(a)
2175540160816
>>> id(b)
2175580224080
>>> a==b
True  #is是身份运算符,两个变量取值相同并不等于身份相同

作业:

集合

>>> a={1, 2, 3}
>>> b={2, 1, 3}
>>> a==b
True #因为集合是无序的
>>> a is b
False

元组

>>> c=(1, 2, 3)
>>> d=(2, 1, 3)
>>> c==d
False
>>> c is d
False

类型type的判断

对象的三大特征:id value type 一切都是对象

位运算符:&(按位与)、|(按位或)、 ^(按位异或)、~(按位取反)、 <<(左移动)、>>(右移动)

什么是表达式

表达式是运算符和操作数所构成的序列

python中运算符优先级为:如图所示,由上到下优先级依次降低

img

>>> 1+2*3
7
>>> 1*2+3
5
>>> a=1
>>> b=2
>>> c=3
>>> a+b*c
7
>>> a or b and c  #b和c先做且运算再和a做或运算
1
>>> 1 or 2
1
>>> 1 and 3
3

解释器在解析表达式优先级的时候,有默认的顺序 ,如果操作符是同级,默认从左向右来解析(左结合);()的优先级最高。

>>> a=1
>>> b=2
>>> c=3
>>> (a or b) and c
3
>>> (a or b) and (c+1)
4

通常来说表达式都遵从左结合,除了赋值运算符=

>>> a=1
>>> b=2
>>> c=a+b  #右结合
>>> print(c)
3
>>> c=a or b
>>> print(c)
1

作业

>>> a=1
>>> b=2
>>> c=2
>>> not a or b + 2 == c
False
 #(not a) or ((b + 2) == c) 

拿到表达式先看有无括号,再看有无等号,如果有等号,则用右结合;

在文本文件中编写python代码

python和其它语言的不同:

1、python在每一行语句的末尾不强制加分号;

2、不需要用{}把代码包裹起来,python靠缩进(四个空格,不是用tab键)来区分代码段。

流程控制语句:条件控制(if else 选择性问题,要有四个空格,结尾有冒号) 循环控制 (for while)

注释: # 单行注释 ‘’'多行注释

mood = True

if mood:
    print('go to left')
else:
    print('go to right')  #如果顶格的话解析器会认为这句话不属于if语句,而会被单独当作一条语句,会报错。
    go to left

if后面的类型是bool类型(若后面的表达式、变量可以被认为是bool类型,则可以成立)

a=1
  b=2
  c=2

  if a or b +1 == c:
    print('go to left')
  else:
    print('go to right')
    go to right

如果某一个变量是空,我们就执行某一个语句,否则执行另外的语句

d=[]
  if d:
     print('go to left')
  else:
     print('go to right')
  go to right

用户密码锁的问题:

account = 'qiyue'
password = '123456' #等号左右要有一个空格,否则会出现波浪线

print('please input account')
user_account = input() #用下划线来分割两个单词

print('please input password')
user_password = input()

if account == user_account and password == user_password:
    print('success')
else:
    print('fail')

python里不存在constant 常量,如果定义了一个常量之后,常量的值是不允许被改变的。

pass 空语句/占位语句 作用:保持代码结构的完整性。

代码块分层(嵌套)

 if condition:
     code1
         code11
         code22
     code2
     code3
 else:
     code1
     code2
     code3

elif(不能单独使用)的写法简化if : else :(if 和 else必须成对出现)

if a==1:
    print('apple')
else:
    if a==2:
        print('orange')
    else:
        if a==3:
            print('banana')
        else:
            print('shopping')
if a == 1:
    print('apple')
elif a == 2:
    print('orange')
elif a == 3:
    print('banana')
else:
    print('shopping')
#elif expression:
#      pass

input():函数得到的是字符串类型

a = input()
print(type(a))
print('a is'+a)
while循环与使用场景

while 循环:给自己设定一个目标,只要达到了这个目标,就会放弃现在正在做的这个事情。(达到了这个目标就将执行else ) 递归算法

for循环:主要是用来遍历/循环(序列、集合或者字典)

代码块的特性:代码块里可以嵌套代码块

无限死循环,会一直出现 i am while

CONDITION = True

while CONDITION:
    print('i am while')

counter=0时while循环自动识别为False,程序不运行。

counter=0

while counter:
    counter += 1
    print(counter)

counter=1时while循环自动识别为True,程序无限循环。

counter=1

while counter:
    counter += 1
    print(counter)

正确用法:

counter=1

while counter <= 10 :
    counter += 1
    print(counter)

输出
2
3
4
5
6
7
8
9
10
11

如何避免while出现死循环:

1、while后面的条件判断语不应该是一个常量,如果是一个常量的话,那么条件判断的结果永远不会改变。换句话说,如果想让while运行的次数是有限的,那么在while内部运行的代码块里就必须要有能够影响这个条件判断的语句。

2、while可以单独使用也可以和else结合起来一起使用。else的作用是当while后面的条件语句返回结果是False的时候将执行else分支后面的代码块。

counter=1

while counter <= 10 :
    counter += 1
    print(counter)
else:
    print('EOF')
  
输出
2
3
4
5
6
7
8
9
10
11
EOF
a = ['apple','orange','banana','grape']
for x in a:
    print(x)#x代表当前这些循环里的列表里的某一个元素,当循环遍历到apple时,x=apple,当循环遍历到orange时,x=orange,当循环遍历到banana时,x=banana,当循环遍历到grape时,x=grape。
D:\Anaconda3\python.exe D:/pythonData/345.py
apple
orange
banana
grape    
a =[ ['apple','orange','banana','grape'],(1,2,3)]
for x in a:
    for y in x:
        print(y)
D:\Anaconda3\python.exe D:/pythonData/345.py
apple
orange
banana
grape
1
2
3

不同于while else(有一个条件判断),for else没有条件判断,当列表里所有元素都被遍历完后,else就会被执行。

for循环之后会打出else后面的语句

a =[ ['apple','orange','banana','grape'],(1,2,3)]
for x in a:
    for y in x:
        print(y)
else:
    print('fruit is gone')
D:\Anaconda3\python.exe D:/pythonData/345.py
apple
orange
banana
grape
1
2
3
fruit is gone

if遇到break跳出循环,立刻结束,不执行break后面的代码

for x in a:
    if x == 2:
        break
    print(x)
D:\Anaconda3\python.exe D:/pythonData/345.py
1

continue当前的x=2不会再执行,但后续的还会执行。

for x in a:
    if x == 2:
        continue
    print(x)
D:\Anaconda3\python.exe D:/pythonData/345.py
1
3

如果for循环不是正常的结束,而是通过break强制打断,是不会执行else里面的语句的

a = [1,2,3]

for x in a:
    if x == 2:
        break
    print(x)
else:
    print('EOF')
D:\Anaconda3\python.exe D:/pythonData/345.py
1    
a =[ ['apple','orange','banana','grape'],(1,2,3)]
for x in a:
    for y in x:
        if y == 'orange':
            break
        print(y)
else:
    print('fruit is gone')
D:\Anaconda3\python.exe D:/pythonData/345.py
apple
1
2
3
fruit is gone

问:加入了break为什么还会有else里面的语句?从orange开始break为什么后面的123还会出现?

答:因为有两个for循环,break执行的是内部的循环,并没有跳出外面的循环,内部的循环跳出后,外部的循环还在执行,所以else依然会执行。

a =[ ['apple','orange','banana','grape'],(1,2,3)]
for x in a:
    if 'banana' in x:#判断的表达式为真,直接跳出循环,else不执行。
        break
    for y in x:
        if y == 'orange':
            break
        print(y)
else:
    print('fruit is gone')
D:\Anaconda3\python.exe D:/pythonData/345.py

for与range:

range(取某个范围里的整数作为循环来遍历)函数可以按照指定的规则来生成一个序列。

for x in range(0,10):#0表示起始数据,10表示偏移量,从0开始总共要有多少个数字。
    print(x)
D:\Anaconda3\python.exe D:/pythonData/345.py
0
1
2
3
4
5
6
7
8
9

for x in range(0,10,2):#2表示步长,间隔多少。
    print(x)
D:\Anaconda3\python.exe D:/pythonData/345.py
0
2
4
6
8

递增的等差数列:
for x in range(0,10,2):
    print(x,end='|')
D:\Anaconda3\python.exe D:/pythonData/345.py
0|2|4|6|8|

递减的等差数列:
for x in range(10,0,-2):
    print(x,end='|')
D:\Anaconda3\python.exe D:/pythonData/345.py
10|8|6|4|2|

len函数:

a = [1,2,3,4,5,6,7,8]

for i in range(0, len(a), 2):
    print(a[i], end='|')
D:\Anaconda3\python.exe D:/pythonData/345.py
1|3|5|7|

不用for循环也可以打出1357
a = [1,2,3,4,5,6,7,8]
b = a[0:len(a):2]
print(b)
D:\Anaconda3\python.exe D:/pythonData/345.py
[1, 3, 5, 7]

高性能、封装性(可复用)、抽象

python项目的组织结构:

包(project ):文件夹;一个包下面可以包含很多个模块

模块:一个一个的文件,这些文件都存在于包里;一个模块可以包含多个类

类:class

函数、变量:不属于组织结构里,是类本身的一个特性

包与模块的名字:包的名字是文件的名字;模块的名字是文件夹的名字。

命名空间:用来区分相同的模块,模块里的内容是完全不相同的。

import导入模块

项目是多个包和多个模块之间的相互调用s

import后面只能跟 module_name 模块名

导入test.py文件 /:

import test#导入test.py文件,导入的文件名字首字母不能为数字
print(test.a)
import (很长的名字) as a #可以简化
from_import_导入变量

from module import a,def

__init__的用法:7-9

如何一次导入多个模块?

包与模块的几个常见错误:

1、包和模块是不会被重复导入的

2、避免循环导入

为什么会报错?

直接循环导入,在执行p1这个文件的时候,最上面这句话from p2 import p2是从p2这个包里导入p2这个变量。from p1 将会执行p2这个模块,形成一个循环,p1运行导入p2,p2运行导入p1。

QQ截图20211112194853

间接循环导入

将p4里的第一句话from p1 import p1注释掉,就不会报错,结果为2

为什么运行p1将p2里的变量打出来了?

导入一个模块的时候,就会执行这个模块里的所有代码。

模块内置变量:

dir函数是用来返回当前模块里的所有变量,以列表的形式。

入口文件和普通模块内置变量的区别:

package 当前模块不属于任何包 name doc 当前模块没有文档注释__file__

__name__的经典应用:

dir函数的用法:想查看某个模块或者某个类下面的相关变量。

要成为一个普通模块,必须要有一个包。除非这个模块不是一个普通模块,而是一个要执行的文件。

相对导入和绝对导入:

绝对导入:从顶级包一直通过点符号连接找到所需要的

相对导入:.表示当前目录 …表示上一层目录 …表示上上一层目录 依次类推

入口文件里不可以用相对路径来导入其他模块,入口文件里只能用绝对路径。

认识函数:

函数的特性

1.功能性:一个函数必须有明确的目的

2.隐藏细节:

3.避免编写重复的代码

4.组织代码:

round保留小数点后面的若干位

print()
a = 1.12386#保留浮点数后面的两位去掉最后三位
result = round(a,2)#2表示保留小数点两位
print(result)
D:\Anaconda3\python.exe D:/pythonData/eight/c1.py

1.12

round函数可以执行四舍五入

print()
a = 1.12386#保留浮点数后面的两位去掉最后三位
result = round(a,3)
print(result)

D:\Anaconda3\python.exe D:/pythonData/eight/c1.py

1.124#round函数可以执行四舍五入
函数的定义及运行特点:
def funcname(parameter_list):#def关键字来定义函数 接着是函数 参数列表要用括号把参数括起来 第一行函数最后要带冒号
    pass #占位符代表函数体(代码块) 要有缩进

1.参数列表(parameter_list)可以没有

2.在这个函数的函数体里,可以用return来返回函数的结果(value);如果函数的函数体里没有renturn这个语句,那么会返回一个None。

作业:

1.实现两个数字的相加

2.打印输入的参数

def add(x,y):
    result = x + y
    return result
def print(code):
    print(code)
D:\Anaconda3\python.exe D:/pythonData/eight/c2.py
    

没有任何的结果打印出来,因为只做了函数的定义,而没有调用函数。

函数定义了之后,必须要有一个地方取调用这个函数,函数才能起作用。

add(1,2)
print('Python')

def add(x,y):
    result = x + y
    return result
def print(code):
    print(code)
   
D:\Anaconda3\python.exe D:/pythonData/eight/c2.py
Traceback (most recent call last):
  File "D:/pythonData/eight/c2.py", line 5, in <module>
    add(1,2)
NameError: name 'add' is not defined

错误分析:先调用add,后定义add,是不可以的。

def add(x,y):
    result = x + y
    return result
def print(code):
    print(code)

add(1,2)
print('Python')

D:\Anaconda3\python.exe D:/pythonData/eight/c2.py
Traceback (most recent call last):
  File "D:/pythonData/eight/c2.py", line 13, in <module>
    print('Python')
  File "D:/pythonData/eight/c2.py", line 10, in print
    print(code)
  File "D:/pythonData/eight/c2.py", line 10, in print
    print(code)
  File "D:/pythonData/eight/c2.py", line 10, in print
    print(code)
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

错误分析:递归

import sys
sys.setrecursionlimit(1000000)

def add(x,y):
    result = x + y
    return result
def print_code(code):
    print(code)

add(1,2)
print_code('Python')

D:\Anaconda3\python.exe D:/pythonData/eight/c2.py
Python

掌握调用顺序:

def add(x,y):
    result = x + y
    return result
def print_code(code):
    print(code)
 #默认为return None
a = add(1,2)
b = print('Python')

print(a,b)

D:\Anaconda3\python.exe D:/pythonData/eight/c2.py
Python
3 None

如何让函数返回多个结果:

return 变量 或者如果不使用return默认为return None

一般函数内部的代码创造return后,return后面的语句是不会执行的。

返回一个damage1

def damage(skill1,skill2,out/ref damage2):#out/ref会使damage2的值在函数运行完之后会发生改变,
# 在函数内部可以通过改变damage2的值,然后在外部使用damage2的值
    damage1
    return damage1
def damage(skill1,skill2):
    damage1 = skill1 * 3
    damage2 = skill2 * 2 + 10
    return damage1,damage2

damages = damage(3,6)
print(type(damages))

D:\Anaconda3\python.exe D:/pythonData/eight/c3.py
<class 'tuple'>
def damage(skill1,skill2):
    damage1 = skill1 * 3
    damage2 = skill2 * 2 + 10
    return damage1,damage2

damages = damage(3,6)
print(damages[0],damages[1])#依靠变量来访问 不建议
print(type(damages))

D:\Anaconda3\python.exe D:/pythonData/eight/c3.py
9 22
<class 'tuple'>

用两个有意义的变量来接收两个变量结果

def damage(skill1,skill2):
    damage1 = skill1 * 3
    damage2 = skill2 * 2 + 10
    return damage1,damage2

skill1_damage,skill_damage = damage(3,6)#用两个有意义的变量来接收两个变量结果

print(skill1_damage,skill_damage)

D:\Anaconda3\python.exe D:/pythonData/eight/c3.py
9 22
序列解包与链式赋值:

三个变量接收三个数值

a = 1
b = 2
c = 3
#三行代码简化为一行
a,b,c = 1,2,3
# 用一个变量来接收三个数值
d = 1,2,3
print(type(d))

a,b,c = d

链式赋值

a,b,c = 1,1,1
a=b=c=1
print(a,b,c)
必须参数与关键参数:

函数的参数

1.必须参数:在函数的参数列表里所定义的参数是必须要传递的,如果不传递会报错。
2.形式参数:在定义函数的过程中,在参数列表里给了x,y,把x,y叫做形式参数。
3.实际参数:在函数调用的过程中,在函数的参数列表里所传递的参数的实际的取值。

4.关键字参数:不用考虑函数参数的顺序,可以任意指定参数的顺序,实现函数的调用。意义:方便,代码的可读性

c = add(y=3,x=2)
#关键字参数的形式,可以在做函数调用的时候,明确告诉python所赋值的实参到底是给哪个形参来赋值的。
#把实参3赋给形参y,把实参2赋给形参x
#定义多少个参数就要传递多少个参数
默认参数

作用:函数参数列表很长,只输入其中一个,就能读出其他的参数。

def print_student_files(name,gender='男',age=18,college='人民路小学'):
    print('我叫'+ name)
    print('我今年' + str(age) + '岁')
    print('我是' + gender + '生')
    print('我在' + college + '上学')

print_student_files('李晓晨','女',18,'人民路小学')
print('~~~~~~~~~~')#分隔符
print_student_files('李晓晨')
print('~~~~~~~~~~')
print_student_files('白芸')
print('~~~~~~~~~~')
print_student_files('赵霞','女',22)

D:\Anaconda3\python.exe D:/pythonData/eight/c6.py
我叫李晓晨
我今年18岁
我是女生
我在人民路小学上学
~~~~~~~~~~
我叫李晓晨
我今年18岁
我是男生
我在人民路小学上学
~~~~~~~~~~
我叫白芸
我今年18岁
我是男生
我在人民路小学上学#只有名字不同,其他都一样
~~~~~~~~~~
我叫赵霞
我今年22岁
我是女生
我在人民路小学上学
可变参数

如何定义一个拥有可变参数的函数?

可变参数会自动组装成一个元组。

*用来定义可变参数列表

def demo(*param):
    print(param)
    print(type(param))

demo(1,2,3,4,5,6)

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
(1, 2, 3, 4, 5, 6)
<class 'tuple'>
def demo(*param):
    print(param)
    print(type(param))

demo((1,2,3,4,5,6))

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
((1, 2, 3, 4, 5, 6),)#二维元组
<class 'tuple'>
def demo(*param):
    print(param)
    print(type(param))
a = (1,2,3,4,5,6)
demo(a)

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
((1, 2, 3, 4, 5, 6),)
<class 'tuple'>


def demo(*param):
    print(param)
    print(type(param))
a = (1,2,3,4,5,6)
demo(*a)#加*的作用:把元组里的每个元素平铺出来 ,把它的元素拿进来,传递给可变参数。

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
(1, 2, 3, 4, 5, 6)
<class 'tuple'>

必须参数必须放在可变参数前面

def demo(param1,param2=2,*param):
    print(param1)
    print(param2)
    print(param)

demo('a',1,2,3)#可以跳过param2,传可变参数列表*param吗?

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
a #print(param1)必须参数
1 #print(param2) 因此没有办法跳过默认参数
(2, 3)#因为把1赋值给了param2默认参数,所以可变参数列表只有(2,3)
def demo(param1,*param,param2=2):
    print(param1)
    print(param)
    print(param2)

demo('a',1,2,3,'param')

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
a  #
(1, 2, 3, 'param') #把1,2,3,'param'参数默认算在可变参数里
2 #由于param2是默认参数,计算机会觉得没有传值,所以param2取它的默认值2。
def demo(param1,*param,param2=2):
    print(param1)
    print(param)
    print(param2)

demo('a',1,2,3,param2 = 'param')#用关键字参数来指定param2等于新的取值,而不是它的默认值。

D:\Anaconda3\python.exe D:/pythonData/eight/c7.py
a
(1, 2, 3)
param
关键字可变参数:

可变参数绝大多数都是用for循环来遍历可变参数里的每个参数,然后再拿出来使用。

可变参数列表的优点:简化函数的调用,

def squsum(*param):#squsum函数的作用是把输入的任意个数的数字求平方和,再输入出来。
    sum = 0
    for i in param:
        sum += i*i
    print(sum)

squsum(1,2,3,4,5,6)

D:\Anaconda3\python.exe D:/pythonData/eight/c8.py
91

def city_temp(*param):#*不能接受可变的关键字参数列表,**才可以

city_temp(bj='32c',xm='23c',sh='31c')

D:\Anaconda3\python.exe D:/pythonData/eight/c8.py
  File "D:/pythonData/eight/c8.py", line 12
    city_temp(bj='32c',xm='23c',sh='31c')
    ^
IndentationError: expected an indented block
    
def city_temp(**param):#*不能接受可变的关键字参数列表,**才可以
    pass
city_temp(bj='32c',xm='23c',sh='31c')

D:\Anaconda3\python.exe D:/pythonData/eight/c8.py

Process finished with exit code 0
def city_temp(**param):
    print(param)
    print(type(param))
    pass
city_temp(bj='32c',xm='23c',sh='31c')

D:\Anaconda3\python.exe D:/pythonData/eight/c8.py
{'bj': '32c', 'xm': '23c', 'sh': '31c'}
<class 'dict'>
def city_temp(**param):
    for key,value in param.items():
        print(key,':',value)

city_temp(bj='32c',xm='23c',sh='31c')

D:\Anaconda3\python.exe D:/pythonData/nine/c3.py
bj : 32c
xm : 23c
sh : 31c
变量作用域:

每一个变量都有它的作用范围,这个范围就是变量的作用域。

c = 50

def add(x, y):
    c = x + y
    print(c)

add(1,2)#调用函数
print(c)

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
3
50
def demo():#局部变量(函数内部)
    c = 10#外部无法使用局部变量

print(c)

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
Traceback (most recent call last):
  File "D:/pythonData/eight/c9.py", line 13, in <module>
    print(c)
NameError: name 'c' is not defined
#错误分析:因为C这个变量作用域仅仅局限于这个函数的内部,对c的引用超出了c的变量作用域。
c = 10#全局变量(函数外部)
def demo():
   print(c)

demo()

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
10
#函数外部的变量作用域覆盖整个模块文件,可以在函数内部引用函数外部的变量
def demo():
    c = 50
    for i in range(0,9):
        c += 1
    print(c)
demo()

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
59
#局部变量是一个相对概念,c=50对于for循环来说并不是一个局部变量。

for循环外部可以引用for循环内部的变量(其他语言里不存在,python独有的)

def demo():
    c = 50
    for i in range(0,9):
        a = 'a'
        c += 1
    print(c)
    print(a)
demo()

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
59
a
#for循环外部可以引用for循环内部的变量

作业:

c = 1

def func1():
    c = 2
    def func2():
        c = 3
        print(c)
    func2()

func1()

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
3
def func1():
    c = 2
    def func2():
        print(c)
    func2()#可以访问c=2

func1()

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
2
def func1():
    def func2():
        print(c)
    func2()

func1()

D:\Anaconda3\python.exe D:/pythonData/eight/c9.py
1
_global关键字:

全局变量如果不做特别的限制,整个应用程序里都可以应用。

global的作用:把一个变量变成全局变量

def demo():
    global c = 2
    
print(c)

D:\Anaconda3\python.exe D:/pythonData/eight/c11.py
  File "D:/pythonData/eight/c11.py", line 2
    global c = 2
             ^
SyntaxError: invalid syntax
def demo():
    global c #global可以把c变成一个全局变量
    c = 2

demo()
print(c)#想要c出现,要调用这个函数

D:\Anaconda3\python.exe D:/pythonData/eight/c11.py
2
类的定义:

类(方法)=面向对象(抽象)

类是面向对象一个基本的概念。

类的命名:第一个字母大写(变量的第一个字母小写);两个单词连接时首字母大写(变量的两个单词之间用_进行连接)

类的内部可以定义若干个变量;

类的定义:封装一系列的变量和一系列的函数。

基本作用:封装代码

类只负责去描述,不负责运行代码;运行类要放在类的外部。

不要在类的内部去调用函数和方法。

class Student():
    name = '' 
    age = 0
    
    def print_file():
        pass
class Student():
    name = ''#全局变量
    age = 0

    def print_file(self):#如何调用类里的print_file函数
        print('name:' + name)
        print('age:' + str(age))

student = Student()
student.print_file()#实例化:

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
Traceback (most recent call last):
  File "D:/pythonData/nine/c1.py", line 10, in <module>
    student.print_file()#实例化:
  File "D:/pythonData/nine/c1.py", line 6, in print_file
    print('name:' + name)
NameError: name 'name' is not defined
class Student():
    name = ''#全局变量
    age = 0

    def print_file(self):#如何调用类里的print_file函数
        print('name:' + self.name)#类下面的函数一定要加self,否则会报错;用self.操作符 来引用;直接使用name会报错。
        print('age:' + str(self.age))

student = Student()
student.print_file()#实例化:

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
name:
age:0
浅谈函数与方法的区别:

不要在一个模块里既去定义一个类又去实例化和调用类;要么就定义类,要么就执行和类相关的实例化和调用类

函数与方法的区别:

方法:是设计层面的一个称谓,更多的是面向对象的一个概念,面向对象更加关注的是设计,设计代码的结构,设计封装

函数:程序运行、过程式的一种称谓,更多的是面向过程的一个概念,没有设计层面的意义在里面

数据成员:更多的在于体现类的封装性,每一个变量都可以被视作一个数据,数据用来描述类的特征

类与对象:

类与对象是通过实例化关联在一起的,

类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起

数据成员刻画某个事物的行为与特征(行为用方法来表示)

类是抽象的概念,对象是具体的概念

构造函数:

构造函数的作用:让模板生成不同的对象,可以通过构造函数增加参数传入不同的值让对象变得不同

怎样在实例化的后让这几个对象不相同?在student的内部定义一个函数

class Student():
    name = ''#全局变量
    age = 0

    def  __init__(self):# 双下划线:构造函数
        print('student')

    def do_homework(self):
        print('homework')      
student1 = Student()
student2 = Student()
student3 = Student()

print(id(student1))
print(id(student2))
print(id(student3))

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
student
student
student
1320357041776
1320357041440
1320357040816     

如果想访问类下面的变量或某一个方法,通过 . 来操作

区别模块变量与类中的变量:
c = 50#全局变量

def add(x,y):
    c = x + y #c与c=50不是同一个c,c仅仅作用在函数内部
    print(c) 

add(1,2)
print(c)#打出c不会因为局部变量而改变,所以最后输出的还是50

D:\Anaconda3\python.exe D:/pythonData/nine/c5.py
3
50
类变量与实例变量:

类变量:和类相关的变量

实例变量:和对象相关的变量;使用self加上所定义的实例变量的名字构成一个完整的实例变量

对象必须有一个地方保存它的特征值:使用self.name保存name的特征值;使用self.age保存age的特征值

类变量里定义变量与具体的变量无关

类与对象的变量查找顺序:
class Student():
    name = 'qiyue'#全局变量
    age = 0

    def  __init__(self,name,age):
        name = name
        age = age
    def do_homework(self):
        print('homework')
student1 = Student('石敢当',18)
print(student1.name)
print(Student.name)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
qiyue#实例变量打印的(打印出两个变量,一般都是两种不同变量)
qiyue#类变量打印的
class Student():
    name = 'qiyue'#全局变量
    age = 0

    def  __init__(self,name,age):
        self.name = name#self.标志着实例变量
        self.age = age
    def do_homework(self):
        print('homework')
student1 = Student('石敢当',18)
print(student1.__dict__)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
{'name': '石敢当', 'age': 18}
__self与实例方法:

self 是当前调用某一个方法的对象

实例方法:实例可以调用的方法,特点:第一个参数需要传入一个self

self可以在实例方法里任意更改名字;cls可以在类方法里任意更改名字

在实例方法中访问实例变量与类变量:

python类:

1.变量:a.类变量 b.实例变量

2.方法:a.类方法 b.实例方法 c.静态方法

类方法的作用:操作和类相关的变量

方法最本质的意义:多数情况下,方法需要对变量做一系列运算或者是逻辑上的操作,最终改变变量的状态

方法如何访问变量:实例方法操作实例变量 (self.操作符)

3.构造函数:

4.成员的可见性

5.面向对象三大特性:a.继承性 b.封装性 c.多态性

实例方法里访问类变量:

class Student():
    sum1 = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        print(Student.sum1)
    def do_homework(self):
        print('homework')
student1 = Student('石敢当',18)
print(student1.name)
print(Student.name)#

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
0
Traceback (most recent call last):
石敢当

方法一:

class Student():
    sum1 = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        
        print(Student.sum1)
        
    def do_homework(self):
        print('homework')
student1 = Student('石敢当',18)
print(student1.name)
print(Student.sum1)#

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
0
石敢当
0

方法二:通过self来访问

class Student():
    sum1 = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        
        print(self.__class__.sum1)
        
#通过self名称来访问类变量,class指代student类,然后通过class再次访问sum1
    def do_homework(self):
        print('homework')
student1 = Student('石敢当',18)
print(student1.name)
print(Student.sum1)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
0
石敢当
0

类变量的作用,正确使用场景,实例方法也可以操作类变量

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        print('当前班级学生总数为:' + str(self.__class__.sum))
#实例变量的初始化通常是在构造函数里进行的
    def do_homework(self):
        print('homework')
student1 = Student('李',12)
student2 = Student('晓',17)
student3 = Student('晨',10)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
当前班级学生总数为:1
当前班级学生总数为:2
当前班级学生总数为:3                

如何定义一个类方法?

​ 类方法的定义遵循函数的基本定义方,使用def关键字,接着是方法名plus_sum(),然后使用cls(class的简写,实例方法是self),定义类方法还需要在上面加上一个特殊标记@classmethod,其中@这样的形式在python里叫做装饰器

判断一个方法是实例方法还是类方法的根本原因:在方法的上面是否有装饰器@classmethod,而不是因为参数列表里面的名字不同,名字不同不能决定它是什么类型的方法

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        print('当前班级学生总数为:' + str(self.__class__.sum))
    
    def do_homework(self):
        print('homework')

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(cls.sum)
student1 = Student('李',12)
Student.plus_sum()
#每当我们实例化一个对象之后,如果我们想让班级的学生总数加一,我们可以通过类二层student来使类变量加上一
student2 = Student('晓',17)
Student.plus_sum()
student3 = Student('晨',10)
Student.plus_sum()

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
当前班级学生总数为:1 #self.__class__.sum += 1,所以从0变到1
2       #接着调用了Student.plus_sum(),所以从1变到2
当前班级学生总数为:3
4
当前班级学生总数为:5
6        

区别:实例方法所关联的是对象,类方法关联的是类本身;

用对象来调用类的方法:(一般不用)其它语言里行不通

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        print('当前班级学生总数为:' + str(self.__class__.sum))
    def do_homework(self):
        print('homework')

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(cls.sum)
student1 = Student('李',12)
student1.plus_sum()

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
当前班级学生总数为:1
2
静态方法:

静态方法:使用def关键字,定义函数,上面有装饰器@staticmethod

静态方法和类方法、实例方法有什么不同:

静态方法没有像类方法、实例方法一样强制默认指定的名字(类方法里cls代表类的真,实例方法里self代表对象的真),没有任何的指代参数

如果想让一个函数成为一个静态方法需要在方法上面加上@staticmethod装饰器

静态方法可以同时被类和对象调用

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        print('当前班级学生总数为:' + str(self.__class__.sum))
    def do_homework(self):
        print('homework')

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(cls.sum)

    @staticmethod
    def add(x,y):#静态方法:使用def关键字,定义函数,上面有装饰器@staticmethod
        print('This is a static method')
#如何调用静态方法:一个对象、一个类可以调用静态方法


student1 = Student('李',12)
student1.add(1,2)#student对象调用静态方法
Student.add(1,2)#student类调用静态方法
# 静态方法可以同时被类和对象调用

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
当前班级学生总数为:1
This is a static method
This is a static method

静态方法没有显示的传入类;类方法把cls显示的传入进来

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        print('当前班级学生总数为:' + str(self.__class__.sum))
    def do_homework(self):
        print('homework')

    @classmethod
    def plus_sum(cls):#类方法把cls显示的传入进来
        cls.sum += 1
        print(cls.sum)

    @staticmethod
    def add(x,y):#静态方法没有显示的传入类
        print(Student.sum)#静态方法的内部可以访问类变量
        print('This is a static method')

student1 = Student('李',12)
student1.add(1,2)
Student.add(1,2)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
当前班级学生总数为:1
1
This is a static method
1
This is a static method

类方法和静态方法不可以访问实例变量

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        
    def do_homework(self):
        print('homework')

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)
        
student1 = Student('李',12)
student1.add(1,2)
Student.add(1,2)
student1.plus_sum()
Student.plus_sum()

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
Traceback (most recent call last):
  File "D:/pythonData/nine/c1.py", line 27, in <module>
    student1.add(1,2)
  File "D:/pythonData/nine/c1.py", line 20, in add
    print(self.name)
NameError: name 'self' is not defined
成员可见性公开和私有:
class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1
        
    def do_homework(self):
        self.do_english_homework()
        print('homework')  
        
    def do_english_homework(self):
        print()
        #内部调用:在do_homework方法的内部调用do_english_homework   
        # 类的内部一个函数可以去调用另外的一个函数

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)
student1 = Student('李',12)
student1.do_homework()#外部调用:在类的外部通过student1对象的外部访问和调用do_homework方法
class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.score = 0#表示对象下面有score实例变量,但是目前只是一个初始状态,还没有打分
        self.__class__.sum += 1

    def marking(self,score):#如何通过marking方法来给学生打分?接收一个参数score,在marking的内部给score赋值
        self.score = score
        print(self.name + '同学本次考试分数为:' + str(self.score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()
        #内部调用:在do_homework方法的内部调用do_english_homework
        # 类的内部一个函数可以去调用另外的一个函数

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
student1.do_homework()#外部调用:在类的外部通过student1对象的外部访问和调用do_homework方法
student1.marking(60)#正确打分方式
#student1.score = -1#错误打分方式:负分会造成类的内部数据不安全,
#正确的设置分数的方式:不应该是直接通过操作变量的方式来给它赋值,对于分数打分的操作只应该由内部的类来操作分数

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py

homework
李同学本次考试分数为:60

方法一:

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.score = 0#表示对象下面有score实例变量,但是目前只是一个初始状态,还没有打分
        self.__class__.sum += 1

    def marking(self,score):#如何通过marking方法来给学生打分?接收一个参数score,在marking的内部给score赋值
        if score < 0:
            score = 0#分数不会有负数,保证数据的安全
           #或者return'不能够给别人打负分'

        self.score = score
        print(self.name + '同学本次考试分数为:' + str(self.score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
result = student1.marking(-1)
print(result)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
李同学本次考试分数为:0
None

方法二:

class Student():
    sum = 0
    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.score = 0#表示对象下面有score实例变量,但是目前只是一个初始状态,还没有打分
        self.__class__.sum += 1

    def marking(self,score):#如何通过marking方法来给学生打分?接收一个参数score,在marking的内部给score赋值
        if score < 0:
            return '不能够给别人打负分'#分数不会有负数,保证数据的安全

        self.score = score
        print(self.name + '同学本次考试分数为:' + str(self.score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
result = student1.marking(-1)
print(result)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
不能够给别人打负分

规范:一个类下面的数据变量是类非常重要的特征数据,一般来说,如果要修改类的特征的值,不应该通过直接访问变量的方式来改变变量的状态;所有对于类下面的变量更改,应该通过方法来完成

成员可见性的状态:

1.公开的public:可以在类的外部直接访问

2.私有的private:在外部无法直接读取或设置

没明确表示类的外部是公开的,可以在外部随意读和写这个变量

有什么方法可以阻止其他人从类的外部直接对类的变量进行赋值或者读取操作?

​ 成员可见性,在变量或方法前面加双下划线让它变成私有的变量

如何决定一个变量或方法的成员可见性?

​ 对于一个变量或方法,开头不是__双下划线都会认为是公开的,反之,是私有的

class Student():
    sum = 0

    def  __init__(self,name,age):
#为什么python可以让双下划线开头的init从外部来访问?
#因为init前后都有双下划线
        self.name = name
        self.age = age
        self.score = 0
        self.__class__.sum += 1

    def marking(self,score):
        if score < 0:
            return '不能够给别人打负分'

        self.score = score
        print(self.name + '同学本次考试分数为:' + str(self.score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
result = student1.__marking(59)
print(result)
student1.score = -1
r = student1.score

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
Traceback (most recent call last):
  File "D:/pythonData/nine/c1.py", line 33, in <module>
    result = student1.__marking(59)
AttributeError: 'Student' object has no attribute '__marking'

为什么构造函数有双下划线,依然可以在外部访问?

​ 因为构造函数属于python特有的函数,可以从外部访问

如果想让一个方法或者是变量变成私有的在变量名前面加双下划线就可以了

class Student():
    sum = 0

    def  __init__(self,name,age):
#为什么python可以让双下划线开头的init从外部来访问?
#因为init前后都有双下划线
        self.name = name
        self.age = age
        self.score = 0
        self.__class__.sum += 1

    def __marking__(self,score):
        if score < 0:
            return '不能够给别人打负分'

        self.score = score
        print(self.name + '同学本次考试分数为:' + str(self.score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
result = student1.__marking__(59)
print(result)
student1.score = -1
r = student1.score

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
李同学本次考试分数为:59
None
class Student():
    sum = 0

    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__score = 0
        self.__class__.sum += 1

    def marking(self,score):
        if score < 0:
            return '不能够给别人打负分'

        self.__score = score
        print(self.name + '同学本次考试分数为:' + str(self.__score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
result = student1.marking(59)
print(result)
student1.__score = -1

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
李同学本次考试分数为:59
None

作业:为什么给方法加双下划线会变成一个私有的,强行从外面调用它会报错,但是实例变量加双下划线后,再从外部强行访问它,却没有报错?

没有什么是不能访问的:
class Student():
    sum = 0

    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__score = 0
        self.__class__.sum += 1

    def marking(self,score):
        if score < 0:
            return '不能够给别人打负分'

        self.__score = score
        print(self.name + '同学本次考试分数为:' + str(self.__score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
student2 = Student('晓',12)

result = student1.marking(59)
print(result)
student1.__score = -1#(__score和原来的score是两个不同的实例变量)

print(student1.__score)
print(student2.__score)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
Traceback (most recent call last):
李同学本次考试分数为:59
  File "D:/pythonData/nine/c1.py", line 40, in <module>
None
-1
    print(student2.__score)
AttributeError: 'Student' object has no attribute '__score'
class Student():
    sum = 0

    def  __init__(self,name,age):
        self.name = name
        self.age = age
        self.__score = 0
        self.__class__.sum += 1

    def marking(self,score):
        if score < 0:
            return '不能够给别人打负分'

        self.__score = score
        print(self.name + '同学本次考试分数为:' + str(self.__score))
    def do_homework(self):
        self.do_english_homework()
        print('homework')

    def do_english_homework(self):
        print()

    @classmethod
    def plus_sum(cls):
        cls.sum += 1
        print(self.name)

    @staticmethod
    def add(x,y):
        print(self.name)

student1 = Student('李',12)
student2 = Student('晓',12)

result = student1.marking(59)
print(result)
student1.__score = -1
print(student1.__dict__)
print(student2.__dict__)

D:\Anaconda3\python.exe D:/pythonData/nine/c1.py
李同学本次考试分数为:59
None
{'name': '李', 'age': 12, '_Student__score': 59, '__score': -1}
{'name': '晓', 'age': 12, '_Student__score': 0}
继承:

继承性最基本的作用:避免定义重复的方法和重复的变量

可以允许有多继承

from c6 import Human

class Student(Human):

    def do_homework(self):
        print('english homework')

student1 = Student('李',18)
print(student1.sum)#从实例上访问sum
print(Student.sum)#从类上访问sum
print(student1.name)
print(student1.age)#实例变量可以被子类继承

D:\Anaconda3\python.exe D:/pythonData/nine/c5.py
0
018
from c6 import Human

class Student(Human):

    def do_homework(self):
        print('english homework')

student1 = Student('李',18)
print(student1.sum)#从实例上访问sum
print(Student.sum)#从类上访问sum
print(student1.name)
print(student1.age)#实例变量可以被子类继承
student1.get_name()

D:\Anaconda3\python.exe D:/pythonData/nine/c5.py
0
018#由student1.get_name()打印出来的
子类方法调用父类方法super关键字:
from c6 import Human

class Student(Human):
    def __init__(self,schoool,name,age):
        self.school = school
        Human.__init__(self,name,age)#在子类里调用父类的函数,Human是一个类不是对象
        #构造函数的参数看成是实例方法,类调用实例方法是不正确的,因为类是抽象的,对象是具体的,用一个类去调用一个实例方法是说不通的

    def do_homework(self):
        print('english homework')

student1 = Student('人民路小学','李',18)#完成实例化
student1.do_homework()#python知道def do_homework(self)中的self指的是student1,所以可以自动的把student1传入到do_homework()里来
#为什么Human.__init__(self,name,age)需要传入self,而在实例化的时候不需要传入?
#实例化的时候确实调用了构造函数,但是这个调用构造函数的调用方式不是自己去调用构造函数,是python内部的实例化机制自动帮我们调用的构造函数
from c6 import Human

class Student(Human):
    def __init__(self,school,name,age):
        self.school = school
        Human.__init__(self,name,age)
        super(Student,self).__init__(name,age)#调用父类的构造函数的方式:引入关键字super,super很多时候都代表父类的关键字

    def do_homework(self):
        print('english homework')

student1 = Student('人民路小学','李',18)
Student.do_homework(student1)

print(student1.name)
print(student1.age)

D:\Anaconda3\python.exe D:/pythonData/nine/c5.py
english homework
李
18
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值