python高阶

本文介绍了Python中的面向对象编程概念,包括类的定义、实例化、方法、属性以及继承。同时讲解了正则表达式的使用,如match和search函数,以及如何进行字符串的检索和替换。此外,还涉及到了CGI编程的基础,如使用cgi模块处理HTTP表单数据,以及网络编程中的Socket服务。
摘要由CSDN通过智能技术生成

面向对象

class Employee:
   '所有员工的基类'
   empCount = 0
 
   def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.empCount += 1
   
   def displayCount(self):
        print ("Total Employee %d" % Employee.empCount)
 
   def displayEmployee(self):
        print ("Name : ", self.name,  ", Salary: ", self.salary)

empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Employee.empCount 访问。 第一种方法init()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法 self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

#self代表类的实例,而非类

class Test:
    def prt(self):
        print(self)
        print(self.__class__)
 
t = Test()
t.prt()

在这里插入图片描述

从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。 self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的:

#创建实例对象、访问属性

class Employee:
   '所有员工的基类'
   empCount = 0
 
   def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.empCount += 1
   
   def displayCount(self):
        print ("Total Employee %d" % Employee.empCount)
 
   def displayEmployee(self):
        print ("Name : ", self.name,  ", Salary: ", self.salary)
 
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayCount()
emp2.displayCount()
emp1.displayEmployee()
emp2.displayEmployee()
print ("Total Employee %d" % Employee.empCount)

在这里插入图片描述

emp1.age = 7  # 添加一个 'age' 属性
emp1.age = 8  # 修改 'age' 属性
del emp1.age  # 删除 'age' 属性

hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(emp1, 'age')    # 删除属性 'age

Python内置类属性 dict : 类的属性(包含一个字典,由类的数据属性组成) doc :类的文档字符串 name: 类名 module: 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块mymod中,那么className.module 等于 mymod) bases : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

class Employee:
   '所有员工的基类'
   empCount = 0
 
   def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.empCount += 1
   
   def displayCount(self):
        print ("Total Employee %d" % Employee.empCount)
 
   def displayEmployee(self):
        print ("Name : ", self.name,  ", Salary: ", self.salar) 
print ("Employee.__doc__:", Employee.__doc__)
print ("Employee.__name__:", Employee.__name__)
print ("Employee.__module__:", Employee.__module__)
print ("Employee.__bases__:", Employee.__bases__)
print ("Employee.__dict__:", Employee.__dict__)

在这里插入图片描述

#python对象销毁(垃圾回收)

class Point:
    def __init__( self, x=0, y=0):
        self.x = x
        self.y = y
    def __del__(self):
        class_name = self.__class__.__name__
        print (class_name, "销毁")
pt1 = Point()
pt2 = pt1
pt3 = pt1
print (id(pt1), id(pt2), id(pt3)) # 打印对象的id
del pt1
del pt2
del pt3

在这里插入图片描述

在python中继承中的一些特点: 1、如果在子类中需要父类的构造方法就需要显示的调用父类的构造方法,或者不重写父类的构造方法。详细说明可查看:python 子类继承父类构造函数说明。 2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数 3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。 如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

class Parent:   # 定义父类
    parentAttr = 100
    def __init__(self):
        print ("调用父类构造函数")
 
    def parentMethod(self):
        print ('调用父类方法')
 
    def setAttr(self, attr):
        Parent.parentAttr = attr
 
    def getAttr(self):
        print ("父类属性 :", Parent.parentAttr)
class Child(Parent): # 定义子类
    def __init__(self):
        print ("调用子类构造方法")
 
    def childMethod(self):
        print ('调用子类方法') 
c = Child()          # 实例化子类
c.childMethod()      # 调用子类的方法
c.parentMethod()     # 调用父类方法
c.setAttr(200)       # 再次调用父类的方法 - 设置属性值
c.getAttr()          # 再次调用父类的方法 - 获取属性值

在这里插入图片描述

你可以使用issubclass()或者isinstance()方法来检测。 issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup) isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。

#方法重写

class Parent:        # 定义父类
    def myMethod(self):
        print ('调用父类方法')
class Child(Parent): # 定义子类
    def myMethod(self):
        print ('调用子类方法') 
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法

在这里插入图片描述

#运算符重载

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b
 
    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)
   
    def __add__(self,other):
        return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

在这里插入图片描述

类属性与方法 类的私有属性 private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.private_attrs。 类的方法 在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数 类的私有方法 private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.private_methods

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0    # 公开变量
 
    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)
print(counter.__secretCount)  # 报错,实例不能访问私有变量
#Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性

class Runoob:
    __site = "www.runoob.com"

runoob = Runoob()
print (runoob._Runoob__site)

在这里插入图片描述

单下划线、双下划线、头尾双下划线说明: foo: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。 _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import * __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

正则表达式

re.match函数 re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

import re
print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配

在这里插入图片描述

import re
 
line = "Cats are smarter than dogs"
 
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
#re.I:使匹配对大小写不敏感
#re.M:多行匹配,影响 ^ 和 $
if matchObj:
    print ("matchObj.group() : ", matchObj.group())
    print ("matchObj.group(1) : ", matchObj.group(1))
    print ("matchObj.group(2) : ", matchObj.group(2))
else:
    print ("No match!!")

在这里插入图片描述

re.search方法 re.search 扫描整个字符串并返回第一个成功的匹配

import re
print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配

在这里插入图片描述

#检索和替换

import re
 
phone = "2004-959-559 # 这是一个国外电话号码"
 
# 删除字符串中的 Python注释 
num = re.sub(r'#.*$', "", phone)
print ("电话号码是: ", num)
 
# 删除非数字(-)的字符串 
num = re.sub(r'\D', "", phone)
print ("电话号码是 : ", num)

在这里插入图片描述

#repl 参数是一个函数

def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)
 
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

在这里插入图片描述

参数: pattern : 一个字符串形式的正则表达式 flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为: re.I 忽略大小写 re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境 re.M 多行模式 re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符) re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库 re.X 为了增加可读性,忽略空格和 # 后面的注释

#re.compile 函数

pattern = re.compile(r'\d+')                    # 用于匹配至少一个数字
m = pattern.match('one12twothree34four')        # 查找头部,没有匹配
print(m)

在这里插入图片描述

pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
>>>import re
>>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I)   # re.I 表示忽略大小写
>>> m = pattern.match('Hello World Wide Web')
>>> print m                               # 匹配成功,返回一个 Match 对象
<_sre.SRE_Match object at 0x10bea83e8>
>>> m.group(0)                            # 返回匹配成功的整个子串
'Hello World'
>>> m.span(0)                             # 返回匹配成功的整个子串的索引
(0, 11)
>>> m.group(1)                            # 返回第一个分组匹配成功的子串
'Hello'
>>> m.span(1)                             # 返回第一个分组匹配成功的子串的索引
(0, 5)
>>> m.group(2)                            # 返回第二个分组匹配成功的子串
'World'
>>> m.span(2)                             # 返回第二个分组匹配成功的子串
(6, 11)
>>> m.groups()                            # 等价于 (m.group(1), m.group(2), ...)
('Hello', 'World')
>>> m.group(3)                            # 不存在第三个分组
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group
#findall

pattern = re.compile(r'\d+')   # 查找数字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
 
print(result1)
print(result2)

在这里插入图片描述

# re.finditer
# 和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )

在这里插入图片描述

#re.split()

>>> re.split('\W+', 'runoob, runoob, runoob.')
['runoob', 'runoob', 'runoob', '']
>>> re.split('(\W+)', ' runoob, runoob, runoob.') 
['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', '']
>>> re.split('\W+', ' runoob, runoob, runoob.', 1) 
['', 'runoob, runoob, runoob.']
 
>>> re.split('a*', 'hello world')   # 对于一个找不到匹配的字符串而言,split 不会对其作出分割
['hello world']

r’(.) are (.?) .
解析: 首先,这是一个字符串,前面的一个 r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 r 可有可无。 (.) 第一个匹配分组,. 代表匹配除换行符之外的所有字符。 (.?) 第二个匹配分组,.? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符 后面的一个 .
没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。 matchObj.group() 等同于 matchObj.group(0),表示匹配到的完整文本字符 matchObj.group(1) 得到第一组匹配结果,也就是(.)匹配到的 matchObj.group(2) 得到第二组匹配结果,也就是(.?)匹配到的 因为只有匹配结果中只有两组,所以如果填 3 时会报错。

import re
s = '1102231990xxxxxxxx'
res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})',s)
print(res)
print(res.groupdict())

在这里插入图片描述
CGI编程

# CGI处理模块
import cgi, cgitb 

# 创建 FieldStorage 的实例化
form = cgi.FieldStorage() 

name='菜鸟教程'
url='http://www.runoob.com'
# 获取数据
site_name = form.getvalue(name)
site_url  = form.getvalue(url)

print ("Content-type:text/html")
print
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>菜鸟教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")

在这里插入图片描述
网络编程

Python 提供了两个级别访问的网络服务。: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

socket.socket([family[,type[,proto]]])

参数 family: 套接字家族可以使AF_UNIX或者AF_INET type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM protocol: 一般不填默认为0.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import tkinter
top = tkinter.tk()
# 进入消息循环
top.mainloop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rubyw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值