浅谈python学习 ,老年人看了都能学会的python

特点

  • python的版本中3.2这种偶数版本属于测试版本,3.3属于正式使用版本,2版本里面的偶数是正式版奇数是测试版,这两个版本都会同时更新,属于python的两个主线
  • python可以在任意平台执行,跨平台性非常好,在各个平台环境中可以使用,注释使用 ctrl + /
  • python里面的输出语句可以在python的编辑器下面和python的执行环境(cmd框)中输出结果

注释

  • python里面的注释分为多行和单行注释,单行注释使用#作为注释符号
  • 三个 符号或者三个 符号,三个 符号的多行注释在python2.0版本里面是有效的,在3.0版本以后就失效了

变量

  • python可以一次性给多个变量赋予多个不同的值,=号在语法里面不是数学的=号,而是赋值符号,
  • python语言特别简单,所以没有结束符号,定义变量的时候没有任何特殊的符号,
  • php 里面定义变量$a = 1; js 里面定义变量使用 var a = 1;,python里面定义变量a = 1
x, y, z = “花花”,“宗妹”,“鱼头”
  • print()是系统给的输出方法
x1 = "im so handsome"
x2 = "im so cool"
x3 = "so many girls love me"
print(x1)
print(x2)
print(x3)

...
im so handsome
im so cool
so many girls love me
  • “+”号在python中不是数学的“+”号,尤其是当你的变量都是字符串的时候,那么他就变成了拼接符号,
  • 可以将字符串拼起来,“+”号是无缝拼接的
print(x1+x2+x3)
  ....
  im so handsomeim so coolso many girls love me

print(x1,x2,x3)
  ....
  im so handsome im so cool so many girls love me
  • “,” 号是有缝拼接,在拼接字符串的时候留了空格
x4 = 1
x5 = 2
print(x4+x5)
   ....
   3
   
x6 = "1"
x7 = "2"
print(x6+x7)
   ....
   12  //这是字符串连接12,不是数字12

注意python里面不支持字符串和数字的拼接

x8 = 1
x9 = "2"
print(x8+x9)
   ....
   TypeError: unsupported operand type(s) for +: 'int' and 'str'          //系统报错,整型与字符串无法做运算拼接
  • 局部变量指的是变量可以使用的范围,只能在一定的范围内使用的变量叫局部变量
  • 可以在所有的范围内使用的变量叫全局变量,正常的变量如果定义在方法外面那么就只能在方法外面使用
  • 而方法里面的变量只能在方法里面使用,出了方法体就自动被释放掉了,所以方法体外面和里面的变量不一样
  • 变量最初都是局部变量,除非使用global关键字对这个变量进行二次加工,它才可以变成全局变量,在方法里面和外面都有效
x10 = “awesome”
  • def 是系统给的关键词声明(告诉python这不是变量而是一个方法)方法用的,python方法体定义
  • def关键词+方法名+()接口+:组成,python通过空格来控制方法体,方法定义后所有比他多两个空格的语句都算作在他的方法体里面
def cao():
    global x10
    x10 = "fantastic"
    print(x10)
cao()
print(x10)

   ....
   fantastic
   awesome

python的基础数据类型比其他的语言要更加的细致,所以python在数据流的处理和抓取上面比正常的语言更快,所以python非常适合编写爬虫(针对网页中的内容)或者对数据库(存储和搜索)

数据类型

基础数据类型
文本类型str(字符串)
数值类型int,float,complex
序列类型list,tuple,range
映射类型dict
集合类型set,frozenset
布尔类型bool
二进制类型bytes,bytearray,memoryview

示例:

  • a = "我是你爸66.,.!@#6"
    print(type(a))          //字符串
        ....
        <class 'str'>
    
  • b = 9999999999print(type(b))         //整型   
     ....    
     <class 'int'>
    
  • c = 3.1415print(type(c))        //浮点数  
     ....   
     <class 'float'>
    
  • d = 1j                   //复数数据类型print(type(d))   
     ....    
     <class 'complex'>
    
  • e = ['啊','是','我']print(type(e))           //列表   
     ....    
     <class 'list'>
    
  • f = ('啊','是','我')print(type(f))            //元组    
    ....    
    <class 'tuple'>
    
  • g = {'上海','北京','广州'}
    print(type(g))
    print(g)                  //集合    
    ....   
     <class 'set'>    
     {'上海', '北京', '广州'}
    
  • h = {'女人':'小芳','女孩':'老何','三姨子':'静静'}
    print(type(h))             //字典   
    ....   
    <class 'dict'>
    
  • y = frozenset({'apple','orange','banana','peach'})
    print(y)                    //冰冻集合 
     ....  
     frozenset({'apple', 'peach', 'orange', 'banana'})
    
  • j = Trueprint(type(j))            //布尔型  
    ....  
    <class 'bool'>
    
  • k = b"hi,im good man"
    print(type(k))print(bytearray(5))              //二进制类型
    print(memoryview(bytes(5)))  
    ....  
    <class 'bytes'>  
    bytearray(b'\x00\x00\x00\x00\x00')  
    <memory at 0x0000024C11824340>
    
  • import:
    引入外部的包,因为你不能把所有的组件和功能都默认添加到python的文件,这样会造成一个文件加载半天,

    random是python中随机数的类包,里面所有随机数相关的内容都已经写好,包括属性和方法,我们只要获取到它然后调用这些方法就可以实现各种获取随机数的方法

import random
  • randrange(1,10)这个方法无法获取到10,只能得到1-9的随机整数,python的计算能力比较弱,弱到随机数获取不均匀,所以python从来都不用写任何复杂的计算过程,这些计算过程的能力由java和php来编写
print(random.randrange(1,10))

字符串

  • 字符串是从0开始记位的,一直到字符串结束,空格也算一位,每一个空格都算一位,如果增加空格那么后面的位数顺延
strtest = 'hello big dog'print(strtest[8])  
....
   g
  • 按区间取字符串从第二位到第六位,注意第六位无法获取其实只能渠道2-5是有效的取值区间
print(strtest[2:6]) 
....
   llo
  • 反向取值从-1开始,没有-0,从右往左一直取,结尾以-n的形式结尾,并且可以取到,跟正向取值正好相反
print(strtest[-8:-1])  
....
   big do
  • len() 方法系统给的获取字符串长度的方法,它是length的缩写
print(len(strtest))   
....
   13
  • strip()方法是系统给的方法,可以去除字符串两边的空格,并且不管有多少个空格都去掉
print(strtest.strip())   
....
   hello big dog
  • upper()方法将字符串变大写
print(strtest.upper())   
....
     HELLO BIG DOG   
  • python里面的方法调用结束后不影响后面的变量的值的状态,所以为了保持我们变大写的字符串状态,我们需要将大写的字符串存储到原来的变量中,这样大写的值就替代了原来小写的值,所以变量就发生了状态的改变
strtest = strtest.upper()
print(strtest)    
....
       HELLO BIG DOG   
  • lower(),将大写的变量值转成小写
strtest = strtest.lower()
print(strtest)   
....
     hello big dog   
  • split()方法是系统给的方法,使用方法接口中的指定的条件,对字符串进行切割,切割的字符串会以列表的形式显示存在
strtest1 = "hi im lilili ,are you linglingling," \           
           "he is tom"print(strtest1.split(","))    
....
    ['hi im lilili ', 'are you linglingling', 'he is tom']
  • {}+format() 方法构成将指定的值插入到{}的位置上面,这个结构中{}和format都不可或缺,少一个就不能使用
mynumber  = 12345
younumber = 678910
hisnumber = "JQKA"
mycard = "今天打牌,我的牌是{},你的牌是{},他的牌是{},我们是一条龙"
print(mycard.format(mynumber,younumber,hisnumber))  
.....
  今天打牌,我的牌是12345,你的牌是678910,他的牌是JQKA,我们是一条龙

列表

  • 列表list是一种有序的可更改的特殊集合,里面允许有重复的成员存在
thislist = ['印尼神棍','中东神棍','欧洲神棍','美国神棍','中国和尚','加特林菩萨','大日如来核弹']

列表可以从正向和反向取,正向取是从0开始的,反向取是从-1开始的两个极限都可以取到

print(thislist[1])print(thislist[-1])
....
中东神棍大日如来核弹

列表区间取值取列表中的所有的值,正向反向都可以

print(thislist[2:5])print(thislist[-4:-1])
....
['欧洲神棍', '美国神棍', '中国和尚']['美国神棍', '中国和尚', '加特林菩萨']

字符串和列表的获取长度的方法完全一样说明了,在python中字符串和列表的形式转换非常的频繁
如果不以字符串形式存在那么就应该以列表的形式存在,字符串使用split方法分割成列表,而列表又以遍历的形式重新拼接成字符串,所以在获取长度的方法上一样

print(len(thislist))
....
7
  • for in结构是python里面独有的遍历结构,与其说他是for循环结构不如说是它更像一个遍历,遍历是指将整个数据存储里面的所有的值都遍历一遍,变成一个个单独的字符串的形式
for x in thislist:    
      print(x)
      ....
      印尼神棍
      中东神棍
      欧洲神棍
      美国神棍
      中国和尚
      加特林菩萨
      大日如来核弹
  • append()方法,有序的往列表的结尾上添加内容,每次都在最末尾的地方插入一个新的成员进来,列表中的表项我们叫做成员
thislist.append("nice")
thislist.append("good")
print(thislist)
....
['印尼神棍', '中东神棍', '欧洲神棍', '美国神棍', '中国和尚', '加特林菩萨', '大日如来核弹', 'nice', 'good']
  • insert()方法,可以在指定给的位置插入新的成员,只要这个位置在列表中有,那么就可以插入
    即便我们给了一个不存在的超大的下标,但是list列表也只能输出顺序延伸的下标,而不能跨越式下标增长,
    只能能顺延直到list的顺延最后一个下标出现
thislist.insert(100,"你好,再见")
print(thislist)
....['印尼神棍', '中东神棍', '欧洲神棍', '美国神棍', '中国和尚', '加特林菩萨', '大日如来核弹', 'nice', 'good', '你好,再见']

所以在这个例子中,你只能取到9,而100是没有任何值的

print(thislist[9])
....
你好,再见
  • remove()方法通过指定的成员值来删除指定的成员的方法
thislist.remove("good")

删除掉的成员造成后面的成员的下标向前顺移一位

print(thislist)
print(thislist[8])
....
['印尼神棍', '中东神棍', '欧洲神棍', '美国神棍', '中国和尚', '加特林菩萨', '大日如来核弹', 'nice', '你好,再见']
你好,再见
  • 使用del关键字删除指定的下标的成员
del thislist[0]
print(thislist)
....
['中东神棍', '欧洲神棍', '美国神棍', '中国和尚', '加特林菩萨', '大日如来核弹', 'nice', '你好,再见']

clear()方法 直接清空整个列表,什么都不留

thislist.clear()
print(thislist)
....
[]

合并两个单独的列表成为一个大列表,不管列表里面的值的类型是什么

list1 = ["a","b","c"]
list2 = [1,2,3]//因为列表和字符串性质很相似,所以列表可以使用字符串的拼接方法,直接拼"+"号,因为你们拼的是列表而不是列表里面的值  所以本质是两个小列表融合成一个大列表,所以性质是一样,不管里面的内容是什么类型都可以拼接list3 = list1+list2print(list3)
....
['a', 'b', 'c', 1, 2, 3]

元组

  • 元组tuple是一种有序的并且不可以更改的集合,允许重复的成员
thistuple = ('鱼','饭','肉','辣','炒','煮')
print(thistuple)
.....
('鱼', '饭', '肉', '辣', '炒', '煮')

元组确实是不可以更改,但是可以获取

print(thistuple[2])
print(thistuple[1:5])   //按照下标的范围进行取值,取下标为1的值到5为止,取不到5
....('饭', '肉', '辣', '炒')
  • 元组不可以修改,不可以添加,不可以删除

想修改元组只能曲线修改,先将元组转成列表,在修改完以后转回来

mylist = list(thistuple)
print(mylist)
mylist[2] = "喝水"
thistuple = tuple(mylist)
print(thistuple)
....
('鱼', '饭', '喝水', '辣', '炒', '煮')
  1. 首先使用list()方法将我们刚写好元组强制转成列表类型,并且将它赋予给mylist这个变量

  2. 输出mylist这个变量

  3. 往这个列表中的2号下标的内容中替换成喝水

  4. 最后使用tuple()方法强制将mylist转成元组

  5. 输出元组的值

元组通过成员后面,确定这是一个成员,元组不在乎成员是不是空值,如果没有","号那么就不算一个元组

testtuple = ("这是一个测试元组",)
print(type(testtuple))
....
<class 'tuple'>

元组的值是不能改变的,但是可以合并,其实从性质上讲是因为两滴水融合成了一滴水,水里面的杂质是没有发生改变的

uple1 = ('a','b','c')
tuple2 = (1,2,3)
tuple3 = tuple2+tuple1print(tuple3)
....
(1, 2, 3, 'a', 'b', 'c')

集合

  • 最基础的复合数据类型,它是无序,没有索引,没有重复成员的复合数据类型

集合因为没有索引所以是乱序的,具体会出现由系统随机分配,这个特性造成了集合无法取和读,因为没有下标

thisset = {'apple','banana','yellow peach','pink elephant','tomato','potato'}
print(thisset)
....
{'yellow peach', 'tomato', 'banana', 'pink elephant', 'potato', 'apple'}

add()方法是set集合中的添加方法,可以给集合中添加一个随机位置的值,添加进去的值也开始随机洗牌,但是这个方法一次只能添加一个值

thisset.add("我是你爸爸")
print(thisset)....
{'我是你爸爸', 'banana', 'tomato', 'potato', 'yellow peach', 'pink elephant', 'apple'}

update在英文的原意就是更新,可以以列表的形式将单个列表中的所有的值一次性添加到集合中
所有复合数据结构都源于set,所以儿子孝敬爸爸的钱,就变成了爸爸的钱,那么子类结构里面的值进入父类结构,那么就跟着父类结构走了

thisset.update(['附件','添加','随机添加多个'])
print(thisset)
....
{'pink elephant', 'banana', '随机添加多个', 'tomato', '添加', '我是你爸爸', '附件', 'apple', 'yellow peach', 'potato'}

删除指定的集合成员的方法

  1. remove是直接删除了值,所以成员消失了
  2. discard可以将指定的值的在set集合中的定位给删除掉,相当于天上的风筝被我们剪断了线,所以丢失了,而remove是直接把风筝烧了
thisset.remove("我是你爸爸")
print(thisset)thisset.discard("banana")
print(thisset)
....
{'pink elephant', 'potato', 'tomato', '附件', '添加', 'banana', '随机添加多个', 'yellow peach', 'apple'}
{'pink elephant', 'potato', 'tomato', '附件', '添加', '随机添加多个', 'yellow peach', 'apple'}
  1. clear()方法清空整个集合里面所有的值,但是保留集合的结构
  2. del是直接删除整个结构,什么都没了
thisset.clear()
print(thisset)
....
set()
del thissetprint(thisset)
....
NameError: name 'thisset' is not defined   //集合已经被删除,故报错

集合不能通过“+”号进行拼接,因为无序,不知道谁该在前谁该在后

“+”号只有有顺序的集合才能使用,因为涉及到下标了,所以我们使用union来将两个集合联合起来

set1 = {'啊哈哈哈','为恶如恶如'}
set2 = {'这是一个合并用的集合','欸认识的肌肤','小美女'}
print(set1.union(set2))
....
{'欸认识的肌肤', '这是一个合并用的集合', '小美女', '为恶如恶如', '啊哈哈哈'}

字典

  • 字典dictionary无序的?可变的,有索引的不允许重复成员的特殊集合
    在python3.0版本种子点是有序的,在2.0版本中变成了无序的
    字典中的值都是跟键一一对应的,一个键对应一个值
thisdict = {    '前锋':'詹姆斯',    '中锋':'奥尼尔',    '后卫':'保罗',    'year':'2018'}
thisdict["year"] = 2019      
//我们可以通过修改键值对的方式来将字典的值都改掉
print(thisdict)
....
{'前锋': '詹姆斯', '中锋': '奥尼尔', '后卫': '保罗', 'year': 2019}

thisdict.items() 是将整个字典分为两个方向的数组,这样当使用x和y作为他们的代表进行遍历的时候,就会产生两个数组的值被一起遍历出来的情况

for x ,y in thisdict.items():
    print(x,y)
    ....
        前锋 詹姆斯
        中锋 奥尼尔
        后卫 保罗
        year 2019

通过键删除指定的值,因为键和值都是一一对应,少一个另一个就不能存在

del thisdict["前锋"]
print(thisdict)
....
{'中锋': '奥尼尔', '后卫': '保罗', 'year': 2019}

字典还可以进行复制操作,把整个字典的所有的值都复制到另一个字典中

thisdict = {    "brand":"porsche",    "model":"911",    "year":"2000"}
mydic = thisdict.copy()
print(mydic)
....
{'brand': 'porsche', 'model': '911', 'year': '2000'}
dic1 = {    
            "键" :"第一个键",
            "值" :"第一个值",
         "键值对":"一一对应"
}
dic2 = {
        "公司":"重庆fd之乡想",
        "逼事":"逼事就是多还要机试",
        "应对":"爷不干了"
}
dic3 = {
        "厂商":"启fddd辰",
        "要求":"本科本专业",
        "薪资":"第一年8-15k"
}

字典是可以套字典的

mydiccount = {
             "第一个字典":dic1,
             "第二个字典":dic2,
             "第三个字典":dic3
} 
print(mydiccount)
.....
{'第一个字典': {'键': '第一个键', '值': '第一个值', '键值对': '一一对应'}, '第二个字典': {'公司': '重庆梦之乡想', '逼事': '逼事就是多还要机试', '应对': '爷不干了'}, '第三个字典': {'厂商': '启明星辰', '要求': '本科本专业', '薪资': '第一年8-15k'}}

循环和判断结构

判断结构

if else结构基本结构和其他语言相同,但是语句的书写上面不同

a = 66b = 200
if a>b:
    print("a比b大")
    elif a==b:      
    //python没有elseif只有elif它是简写,也没有条件的()直接裸露在外面,":"后面是方法体,方法体通过空格进行控制    
    print("a和b一样大")
    else:
        print("a小于b")
        ....
        a小于b

and语句可以将两个判断或者两个以上的判断条件拼成一个判断条件只有当两边的判断都成立的时候,这个if判断才成立

c = 500
if a < b and c > a:
    print("两边的判断语句都成立")
    ....
    两边的判断语句都成立

python的判断有可以嵌套的功能,只要控制好空格的位置,那么python语法解析器就会自动帮我们解析python的方法体

所有方法体的控制都是由空格的格式控制进行,而且方法体里面必须要有内容,没有内容就报错,如果非要空方法体那么可以使用pass关键词 对方法体进行填充

x = 52
if x >10:
    print("老板没问题")
    if x >20:
       print("老板就是犯贱")
    else:
       print("真香") 
 ....
  老板没问题 老板就是犯贱

循环结构

循环结构while语句

python的for语句不具有循环的功能,是遍历

i = 1
while i<6:
    print(i)    
    #  +=和=+是等价的,下面的两句是完全一个意思    
    #i +=1    
    #i = i + 1    
    i +=1
    ....
    12345

python中独有的结构是可以在while后面续上else,else不是死的固定结构,根据需求添加就行了

else:    
     print("现在的值就比6要大了")
     ....
     12345现在的值就比6要大了

语言中都有break和continue关键词,

  • break是完全打断当前的循环,并且可以按照我们的要求跳出到指定的某次循环中,不必必须要死在当前这层,break的效果要比continue强,打断后循环彻底停止了

  • 而continue则是这次循环不执行,下次循环继续执行,以上规则也适用于for遍历

test = ["你们已经是老货了","比较耐干","我相信着,相信着我的,你们啊"]
for ao in test:                
//break直接中断所有的方法体从最里层跳到最外层    
    print(ao)    
    if ao == "比较耐干"        
       break 
....
 你们已经是老货了 比较耐干

  for sao in test:
      if sao == "比较耐干":
         print(sao)
         continue 
    .... 
      比较耐干

range()方法,是一个获取一定范围内所有的值的方法,如果写10那么就是0-9取不到10

for nice in range(10):
    print(nice)
    ....
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

range()方法除了必须填的一个值以外还可以填写两个可选值,第一个是开始值,第二个是结束值,第三个是两个极端中间每隔多少个增长一次

for x in range(1,10,2):
    print(x)                    //for遍历也可以拼else
    else:
        print("最后结束了")
    ....
    1
    3
    5
    7
    9
    最后结束了

如果遍历过的循环里面不想写任何语言,那么你需要使用pass关键词,不能有空的循环或者遍历或者方法体

Python pass 是空语句,是为了保持程序结构的完整性

pass 不做任何事情,一般用做占位语句

for y in [1,2,3]:
    pass
    ....
    //直接结束了

函数方法

  • 函数就是方法,方法就是功能,功能就是函数,三个完全就是一个,就是指可以改变某些变量或者某些东西的状态的的过程

  • 参数是在方法体之间传递值的一个东西,因为正常的变量在不声明global的情况下无法进入到方法体里面生效,所以当我们不愿意使用global对变量进行全局声明的时候,就会使用参数将方法外面的值传递到方法里面来

    定义函数、方法、功能: def +方法名+()接口+参数+ : 方法体

​ 你可以把参数想象成一个罐子,从瓶子外面流水进来,或者抽水出去,因为使用全局的global变量破坏了方法的封装性,造成了高耦合低内聚(正常是高内聚低耦合,就是关联少独立性强,增强可重用性、移植性)

高内聚低耦合详解:

的在这里插入图片描述

方法除了可以执行我们指定的程序以外还可以给我们返回结果,程序可以不在方法里面执行

为什么要把程序封装在方法里面,或者对程序进行封装呢?

封装、类、对象

我们不只在当前的页面中调用方法,还准备在其他的页面里面调用方法,封装就是将零碎的代码整合成一个整体的功能块,方便后面进行在其它页面中的调用,多个方法又可以被整合成一个类,这样只要引入类就相当于把多个方法都带过来了,想用哪个就用哪个方法,只需要用类生成对象,也就是类的实例化,这样这个对象就可以调用这个类包含的所有的方法 (类的实例化就是对象)

  • 创建方法使用def关键词+方法名+()接口+:方法体开始符号+方法体组成,接口里面如果写了值那么就是参数,参数在内存中是不存在的,完全是一个壳子,什么都没有只是为了传递外面的值进来,所以才写的
def my_function():
    print("好呀,我耳朵积分多少,但是JFK")
    my_function()
    ....
    好呀,我耳朵积分多少,但是JFK

参数调用

  • 第一种调用方法:直接把值写在了方法调用的接口里面
def my_function(canshu,a,test):
    print("好呀,我耳朵积分多少,但是JFK")
    print(canshu+a)
    print(test)
    my_function(1,2,3)
    ....
    好呀,我耳朵积分多少,但是JFK
    3
    3
  • 第二种调用方法:提前将变量写好,然后将变量放在方法调用的参数位置上,把值传到方法里面去
number1 = 1
number2 = 10
number3 = 100
my_function(number1,number2,number3)
....
好呀,我耳朵积分多少,但是JFK
11
100

除了变量传值以外,还可以使用列表往方法体里面传值,这样一次性就可以把好多个值传到一个方法体里面,在方法体里面,使用遍历对这个结构进行遍历,得到列表中带进来的值,这样就可以在方法外面构建列表或者相似的集合结构,到方法体里面使用

food = ['你好','再见']
def function(food):
    for x in food:        
        print(x)
function(food)
    ....
    你好再见

使用关键字直接在接口中赋值来传递值到方法体内

def function1(child3):
    print("这个年轻人是:"+child3)
    function1(child3="郑州撑住")
    ....
    这个年轻人是:郑州撑住

”+参数名的形式为往方法里面传值,叫做复合参数传值,一旦你这样写,你的参数可以有无数个,就代表我本身不知道到底有多少个参数,所以传值的时候就直接写”“+参数名,从接口中截到的参数自动给它们排下标,从0开始

def function2(*kids):
    print("这个老汉是:",kids[2])
    function2("帅老汉","秃老汉","黑老汉","臭老汉")
    ....
    这个老汉是: 黑老汉

lambda方法

是方法的本质结构,通过它可以在没有方法必要的结构的情况下构建一个可以执行的方法,并且把这个方法的结构赋予x这个变量,所以这个变量就变成了一个没有方法体结构声明的方法体

x = lambda n,m:n*m
print(x(10,20))
....
200

return把结果返回给调用方法的地方。谁调用我,我就返回给谁,我们这里返回的是lambda结构,所以就把 a:a*n返回给了mydick这个变量,这个变量也就变成了一个方法了,所以我在下面调用mydick并且给它一个值

def testfunction(n):
    return lambda a:a*n
    mydick = testfunction(2)
    print(mydick(11))
    ....
    22

面向对象

类的补充

创建类,什么是类呢?方法是零散的python语句的集合体,而类是方法的集合体,对象是类的抽象具现化

类是为了整合所有的属性和方法而存在,一类方法才能在一个指定的类中,类中有根据你们的需求不同有无穷多个方法和属性

python里面没有实例化的new关键词,而是直接把类加上()接口进行实例化,这样就相当于把给抽象具现化成了一个对象

class myclass:      //创建类
    x = 8   
 p1 = myclass()     //把这个没有名字的对象赋给p1,所以这个对象就叫做p1
 print(p1.x)       //使用p1这个对象调用x这个属性的值就是理所当然的了,因为现在p1就代表了myclass
 ....
 8

init()方法

  • init()方法这个方法是内置的方法,所有的方法中默认都有它,对类进行初始化,每次类执行的时候都要先来执行它,我们可以强制来设置它来达到改变方法和类内部的目的

  • init()方法可以预置一些我们需要的属性,所有的属性都附着在self身上,调用它们的时候需要使用self来打点调用,所有在test中的属性和方法都可以收到self,只要你在接口中写了self那么你就可以得到预设的值

  • 如果你不写init方法也可以声明类但是不能给类传任何值进来,通过类把值传进来做成预设的属性,这样这个属性就可以在整个类中的所有方法中使用,就避免了我们在重复的调用方法的时候,尤其是调用多个方法的时候给方法赋值

class test:
    def __init__(self,name,age):
            self.name = name 
            self.age = age 
             def myfunc(self):
                print("my name is"+self.name) 
                print("增幅为:",self.age)        
                print(self)p1 = test("鱼头","222")
                p1.myfunc()
                print("test")
       ....
        my name is鱼头
        增幅为: 222
       <__main__.test object at 0x000001F4B3637F10>    //self的内存地址test

age作为init方法里面的属性,也可以在类实例化,抽象具现化以后进行再次赋值

p1.age = 100
print(p1.age)
....
100

我可以使用pass定义方法的内容和类的内容,这样整个类就是空的,即便用了pass,init()也是没有内容的,但是__init__确实隐性的存在

class test1:
    pass
    ....

继承封装多态

父类

class Father:
    def __init__(self,fname,fbody,fmao):
            self.fname = fname        
            self.fbody = fbody        
            self.fmao  = fmao    
    def printname(self):               
             print(self.fname,self.fbody,self.fmao)

子类使用:在类定义的后面加()+父类方法的名字,来告诉python环境它是我的爸爸,我继承自它
继承指的是子类可以完全的继承得到父类的方法和属性,这样已经写好的方法和属性我们在新的类中就不用再次编写了

子类还可以拥有自己的方法和属性,这些方法和属性父亲没有,这种特性叫做多态

为什么不直接改父类而是由子类继承呢?就是为了拥有多种多样的不同的类,但是基础方法和属性是一样

封装在上面有讲

class Son(Father):
    def __init__(self,fname,fbody,fmao,fdick):        
       super().__init__(fname,fbody,fmao)           
       self.fdick = "大,长,粗,硬,黑,这就是男人的肤色"    
    def welcome(self):        
       print("欢迎你儿子:"+self.fname)        
       print("你的身体是:"+self.fbody)        
       print("你的胡子有:"+self.fmao)        
       print("你的**:"+self.fdick)
    x = Son("张三","胸肌","蓝色的","小")
    x.welcome()
    ....
    欢迎你儿子:张三
    你的身体是:胸肌
    你的胡子有:蓝色的
    你的**:大,长,粗,硬,黑,这就是男人的肤色

super()方法

super()是超级的意思,让你把父类的方法__init__()完全继承,为了子类能够完全继承父类的方法和属性,而不是自己重新写了一遍init

子类的对象除了可以调用自己本身的方法和属性以外还可以使用父类的方法和属性,父类不能反向继承子类,只能以树状的结构一层一层
向下继承,不能逆向继承上来,子类还可以拥有自己的子类,继续往下继承,但是不能超过4层,否则会造成在多个类之间寻源,最后造成内存浪费问题,如果程序内存问题堆积的严重,会造成内存溢出,服务运行速度下降最后宕机

x.printname()
....
张三 胸肌 蓝色的

子类和父类的属性的值相互不影响,各管各的,继承的时候只继承结构不继承值

y = Father("nice","good","greate")
print(x.fname)
....
张三

迭代器

概念

迭代器是手动分布执行的for循环,for循环会自动遍历直到数组或者字符串的最后一位,迭代器手动遍历,还可以自定义迭代器的功能

迭代器是python里面独有的结构,本质就是for迭代的分隔板,把一个完整的for功能分割成了迭代和遍历两个部分

我们都知道for循环在python里不是正常的而是遍历

迭代器在概念里面是一种对象,这个对象包含了可计数数字(默认给所有的这个对象里面的值,属性和方法进行了下移排序)

在python里面迭代器是实现迭代器协议的对象,这意味着迭代器对象可以遍历所有的值,迭代器对象的两个方法__iter__()和__next__()方法,他们两个方法拼在一起组成了一个迭代器对象的完整功能

mytuple = ("apple","banana","cherry")
myit = iter(mytuple)
#使用iter方法将元组强制变成元组迭代器对象,方便我们后面试用next对它进行遍历
print(myit)
#然后我使用next方法对myit进行遍历,注意遍历的时候不是自动的而是手动的,所以一个next方法只能遍历迭代器对象一次
print(next(myit))
print(next(myit))
print(next(myit))
....
apple
banana
cherry

迭代器除了可以迭代复合数据结构以外,还可以迭代字符串,把字符串的内容分成一个个单个的字符

string = "awsl,yyds,cpdd"
myit1 = iter(string)
print(next(myit1))
print(next(myit1))
print(next(myit1))
print(next(myit1))
....
a
w
s
l

迭代器实际就是分两步走的for循环,那么怎么对迭代器进行自定义呢?可以在类里面对迭代器进行我们想要的功能自定义

class MyNumbers:
    #这种写法是我们对原版的迭代器不满意,所以重新写了迭代器,重写迭代器我们就可以在迭代器内部插入我们需要的功能    
    def __iter__(self):    #初始化属性值a的值为1        
        self.a = 1         #返回self        
        return self        
        #重新编写next方法,替代掉系统的next方法    
    def __next__(self):         
    #把self.a传进来给x这个变量        
        x = self.a        
        #让self.a自增1,然后放着不动了        
        self.a += 1       
        #把刚才得到最初的self.a的值返回给调用next方法的地方       
        return x        
        #抽象具现化类,把这个类赋给一个名字叫myclass1的变量,这个变量就转变成了一个对象
myclass1     = MyNumbers()
#对这个使用iter方法将它变成了迭代器对象,把这个迭代器对象赋给
myitermyiter = iter(myclass1)
#最后使用next来执行这个迭代器对象,对他进行变量,所以next方法被调用
print(next(myiter))
print(next(myiter))
print(next(myiter))
     ....
     1
     2
     3

模块与引用

  1. 分模块的的目的:防止所有的代码写在一起,一旦其中的一段代码出了问题整个系统就瘫痪,分模块后,所有模块是独立存在的,几乎不和其他模块进行数据交互和关联,这样修改的时候就比较方便同时确保了系统的稳定性
  2. 引用是将其他的模块复制了一份,引到我当前这个文件中,里面有我要用的功能,所以我提前告诉python我要用这个模块,然后python就把这个模块给了我
  3. python里面认为一个 .py 文件默认就是一个同名的类

beload.py模块

def greeting(name):
    print("大哥来玩呀:"+name)
    person1 ={    
             "name":"bill",    
             "age" :63,    
             "country":"china"
    }
    print()

import 格式

import beload
beload.greeting("充钱侠")
....
哥来玩呀:充钱侠

调用其它模块文件的方法的时候直接使用这个模块的对象,调用,然后除了方法可以调用还可以调用属性的值,属性的值除了变量的单一值以外,还有复合型数据结构

a = beload.person1["age"]
print(a)
....
63

import as 格式

除了可以使用原生的名字对文件进行引入还可以使用别名对文件进行引入,别名引入是不会对原名称文件造成影响的,你用原名和别名都可以

import beload as bl
bl.greeting("别名引入示例")
beload.greeting("能不能呢")
....
大哥来玩呀:别名引入示例
大哥来玩呀:能不能呢

除了整文件引入还有只引入某个方法的引入方式

这种单独引入某个方法或者属性的方法就不需要使用对象来调用了,直接就能使用就跟自己加定义的方法和属性一样

from beload import person1
print(person1)
....
{'name': 'bill', 'age': 63, 'country': 'china'}

json数据格式是最常见的文件传输格式,所有在网络上传输的数据从前端到后台的过程中都会被编码成json格式,方便传输到达目的地后使用json编码,变成明文,python作为后端语言需要解码,也需要加码

import json
x = '{"name":"农大五人组","work":"实习","result":"不幸被团灭123!@#@##"}'
z = json.dumps(x)
print(z)y = json.loads(x)print(y)
....
"{\"name\":\"\u519c\u5927\u4e94\u4eba\u7ec4\",\"work\":\"\u5b9e\u4e60\",\"result\":\"\u4e0d\u5e78\u88ab\u56e2\u706d123!@#@##\"}"
{'name': '农大五人组', 'work': '实习', 'result': '不幸被团灭123!@#@##'}

正则表达式

正则表达式是能够简短的反应条件的一种数据表达式,可以帮我们避免冗余的条件判断,用几个字符就能够形成一定的规则,re是正则表达式的包,里面也有一部分实用的方法

import re
#findall()方法通过正则搜索找到一段文字中所有的符合我们条件的文字,并把它们放在一个列表中
str = "喝了,毒鸡汤,来生还,做中国人"
last = re.findall("毒鸡汤",str)
print(last)
#search()会详细的进行搜索,并且把所有的位置信息什么的都显示出来,但是只能搜索出来它搜到的第一个匹配字符的位置信息,这种叫做精确搜索
last1 = re.search("中国人",str)
print(last1)
#split()方法,通过指定的标点符号或者指定的字符对字符串进行分割,分割后的字符串内容存入列表当中
last2 = re.split(",",str)
print(last2)
....
['毒鸡汤']
<re.Match object; span=(12, 15), match='中国人'>
['喝了', '毒鸡汤', '来生还', '做中国人']

文件处理

python里面可以对文件进行各种操作,包括增删改查

文件要使用先要打开,open()方法可以打开文件,open方法有两个参数第一个是文件名,第二个就是文件打开的模式,

“r” -读取-默认值,打开文件进行读取,如果文件不存在那么久报错

“a” -追加- 打开文件供追加,如果不存在那么就创建文件

“w” -写入- 打开文件进行写入,如果文件不存在那么就创建这个文件

“x” -创建- 创建指定的文件,如果文件存在那么就返回错误

“t” -文本- 默认值,文本模式

“b” -二进制- 二进制模式(例如图像)

#现在只是把文件打开了,还没读呢,所以看不到
f = open("demofile.txt","rt",encoding='utf-8')
f1 = open("二爹现在十分后悔.txt","rt")
print("test")
print(f.read())
print(f1.read())
f.close()
f1.close()
f1 = open("demofile.txt","w",encoding="utf-8")
f1.write("好啊")
f1.close()
#创建文件使用x权限
f2 = open("text.file","x")
#删除文件不是文件操作权限的一部分而是一个单独的包os包
import os
#可以删除所有的文件,包括.py文件
os.remove("text.file")
#删除文件夹操作,要求文件夹必须为空否则就会删除失败

注意在操作文件完之后,都要进行close()关闭操作,不然会造成机器宕机

爬虫

在cmd中安装包

python -m pip install --upgrade pip
//pip更新命令,有的时候pip太久无法安装最新的包

pip install requests

pip iinstall BeautifulSoup4

pip install xlwt #安装excel表格操作包

  import requests                     #requests包里面包含了向网页发出请求的各种类和方法,所以我们后面需要使用它来请求网页  
  import re                           #re包正则表达式包,后面用来绕过正则判断,re包是默认包不需要再次下载和更新  
  import sqlite3                      #进行sqlite数据库操作  
  import xlwt                         #进行excel表格操作

pip是python内部包含的一个包管理工具,帮助我们从官网下载一些需要的包并且将包自动解压配置,适应当前电脑的环境,以达到使用状态,pip有pip1和pip3两个主要使用的版本,用哪个都行,1搞不定的可以用3反之亦然

写爬虫工具

beautifulsoup4是这个系列的第四个版本,英文原意就是美丽汤碗,这个插件是一个专门开发用来快捷构建网络爬虫的第三方库,第三方库是个人或者组织出于博名声,处于方便大众的目的开发出来的功能框架,他把所有的相关的某一方面的功能集成起来,这样使用者只要把这个第三方库,集成到自己的项目中一分钟就可以使用,就不用自己写了,节省了开发时间,加快了开发进度,同时第三方库的各种设置都比较全,都是成熟的功能不需要我们自己再去一点一点扣各种bug,

开源第三方库值得是你可以看到这个第三方库的底层实现代码,从而进行放些和改写,闭源的苦是看不到底层代码的,所以开源的库拓展性比较强但是安全性很差,闭源的反之

soup4是3.0版本以后,其他的版本都是python2.7版本以前才能使用

它是爬虫必备的一个第三方库,主要功能就是从网页里面抓取数据,它会自动的把从网上抓取的数据和从文档中输入进来的数据转成Uncode(0x12/0x44/0xaf/0x51)编码格式,输出的文档和结果就变成我们可以读懂的utf-8,soup4还支持python标准库里面的HTML解析器,还支持大部分的第三方解析器,如果我们不安装它,那么python就用默认的解析器lxml解析器,这个解析器是python自带的,不能直接引用BeautifulSoup,因为它的外层有一个bs4文件夹,必须要从这个文件夹里面引进来

import requests
import re
from bs4 import BeautifulSoup
#requests是我们自己刚才引入的requests的包里面的对象,这个get方法是通过get请求方式
#请求url链接里面的网页内容,你们可以把它理解成这是一次从浏览器里面的请求,把请求的结果赋给变量r,以备使用
r = requests.get(url="http://czt.nmg.gov.cn/")
print(r)
#content是我们获取的页面的内容,说白了就是标签对内容里面的东西,也就是所谓页面数据
#Response英文原意是响应的意思,request是请求,200是相应的字符
print(r.content)

BeautifulSoup()方法里面需要填入两个值,第一个是内容,第二个是解析器
内容就是我们刚才爬下来的网页中的代码和标签里面的内容,第二个值是选择解析器为html和lxml

soup = BeautifulSoup(r.content,"html")
print(soup)
#对解码的结果进行格式化输出,让他具有html的格式
print(soup.prettify())
#我可以通过标签名来获取页面中对应的标签和内容
print(soup.title)
#获取标题标签内容里面的值
print(soup.title.string)
#find_all()方法,bs4里面的返回所有特定名称标签的方法
#name是标签的名称,attrs里面可以以键值对的形式也就是“id”:“nice”来具体选中指定id或者class名称的标签
suoyoudiv = soup.find_all(name="div",attrs={})
print(suoyoudiv)

把爬下来的内容输出到文件中

for x in suoyoudiv:
    print(x.string)    
    f1 = open("只有丑男才不能创建文件.txt","a",encoding="utf-8")    
    f1.write(str(x.string))    
    f1.close()

正则表达式(.*?)以及compile的用法示例

“.*?” 表示非贪心算法,表示要精确的配对

“.*”表示贪心算法,表示要尽可能多的匹配

“()” 表示要获取括弧之间的信息

Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,所以要特别注意:

import re# 定义一个正则表达式并编译r = 
re.compile(r'www.lagou.com/.*/">(.*?)</a>')# 待查找文本
text = '''   <a href=" https://www.lagou.com/yingkou-zhaopin/">营口</a>      
                 <input class="dn" value="https://www.lagou.com/jobs/list_测试?&px=default&city=营口#filterBox"/>   
              </li>   
              <li >   
              <a href=" https://www.lagou.com/yanan-zhaopin/">延安</a>      
                  <input class="dn" value="https://www.lagou.com/jobs/list_测试?&px=default&city=延安#filterBox"/>   
              </li>
              '''
              # 在text字符串中查找所有符合r正则表达式的字符串得到结果result
result = r.findall(text)
print(result)
....
['营口', '延安']

re.s作用

re.S的作用".“下的匹配规则扩展到整个字符串,包括换行符”\n",在正则表达式中,".“的作用是匹配任意字符,”\n"除外,也就是说,它只在一行内匹配,如果有换行那就不行了。而re.S则很好的解决了这一个问题。

import re
a = """sdfkhellolsdlfsdfiooefo:
877898989worldafdsf"""
b = re.findall('hello(.*?)world', a)
c = re.findall('hello(.*?)world', a, re.S)
print('b is ', b)
print('c is ', c)
....
 b is  []
 c is  ['lsdlfsdfiooefo:\n877898989']

使用re.S匹配全文,即整个html,直到找到一个符合条件的div标签才结束。

# 创建正则表达式规则对象,匹配每页里的段子内容,re.S 表示匹配全部字符串内容
pattern = re.compile('<div\sclass="f18 mb20">(.*?)</div>', re.S)
# 将正则匹配对象应用到html源码字符串里,返回这个页面里的所有段子的列表
content_list = pattern.findall(html.decode('gbk'))

总结:

这些都是我在学习python过程中所总结的,对于python小白还是有参考价值的,并且我把python中的那些繁琐难懂的专业术语都翻译成了大白话,只要认真看都能看得懂的,加油吧!
我也是新手第一次写,有错误欢迎指正,写了这么多,给个三连鼓励下吧码农吧🤞🤞!

在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐