Python3 高级功能学习笔记(面向对象和正则表达式)

这篇博客介绍了Python3的高级特性,包括面向对象编程的深入探讨,如__slots__、@property、多重继承、定制类、枚举类和元类的使用。同时,讲解了正则表达式的基础应用,如匹配和分组。内容参考了廖雪峰和菜鸟教程的相关教程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python3 高级功能学习笔记(面向对象和正则表达式)


这篇博客不是完整的python教程,只是我在学习python3时记下的一些容易忘记的或比较重要的知识点,里面的代码大多是转自 廖雪峰的python3教程菜鸟教程 。不管怎样,还是希望本篇博客对读者有用。

面向对象

  • 一个类的定义使用class语句。类里面的函数(方法)一定要有一个参数(可以不写self)
  • 如果类里面定义了 __init()__ 方法,实例化类时会自动调用:
class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
print(x.r, x.i)
  • 类里面有 __ 前缀的都是私有变量,类的外部不可访问。
  • python中也支持类的继承,示例如下。另外还可以多重继承,继承顺序是从右往左。
#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

s = student('ken',10,60,3)
s.speak()
  • 判断一个对象的继承关系不用class(),而用isinstance()
  • 获取属性/方法的三个函数:hasattrgetattrsetattr
  • python中还支持运算符重载:
class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return 'Vector ({}, {})'.format(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)

面向对象(高级功能)

1. 使用__slots__

  • 首先,要知道定义完一个类,并生成一个实例后,给实例赋予一个类里面未定义的属性是允许的。这个属性是该实例特有的,新定义的方法也是一样:
class Student(object):
    pass

s = Student()
s.name = 'Michael'
print(s.name)
def set_age(self, age): 
    self.age = age

from types import MethodType
s.set_age = MethodType(set_age, s)      # 给实例绑定方法的方法比较复杂,如上两行
s.set_age(25)       # 调用实例方法
print(s.age)
  • 如果想给每个实例都绑上一个方法,可以这么做:
def set_age(self, age): 
    self.age = age
Student.set_age = set_age   # 这句话写在调用了实例之后也么事
  • 如果要限制实例的属性,就使用__slots__语句:
class Student(object):
    __slots__ = ('name', 'age')

a = Student()
a.name = 'james'
a.age = 15
a.grade = 4

print(a.name, a.age)
print(a.grade)  # 会报错,因为__slots__限制了可添加的属性
  • 注意:__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的.除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
  • 还有一点:有两种方法可以突破slots的限制。一个是直接在类定义里面添加属性,另一个是通过添加方法来添加属性
class Student(object):
    __slots__ = ('name', 'age')
    grade = 3

a = Student()
a.name = 'james'
a.age = 15

print(a.name, a.age)
print(a.grade)  # 不会报错
from types import MethodType

def set_city(self, city):
    self.city=city

class Student(object):
    __slots__ = ('name', 'age', 'set_city')
    pass

Student.set_city = MethodType(set_city, Student)

a = Student()
a.set_city('Beijing')
print(a.city)
  • 另外从笔记看到的一个细节,代码如下。要注意如下方法定义的age是类属性,而不是实例属性,实例还是没有age属性!:
def set_age(self,age):
    self.age=age

class Stu():
    pass

s=Stu()
a=Stu()

from types import MethodType
Stu.set_age = MethodType(set_age,Stu)

a.set_age(15)   # 通过set_age方法,设置的类属性age的值
s.set_age(11)   # 也是设置类属性age的值,并把上个值覆盖掉

print(s.age,a.age)  # 由于a和s自身没有age属性,所以打印的是类属性age的值

2. 使用@property

  • @property的作用是控制实例化类时属性输入的内容。比如一个属性是分数,使用@property可以让你在输入非整数的数字时报错。具体用法如下:
class Screen(object):

    def __init__(self,w,h):
        self.width = w
        self.height = h

    @property
    def width(self):
        return self.th

    @width.setter
    def width(self, value):
        if not isinstance(value, int):
            raise ValueError('input must be an integer!')
        self.th = value

    @property
    def height(self):
        return self._height

    @height.setter
    def height(self, value):
        if not isinstance(value, int):
            raise ValueError('input must be an integer!')
        self._height = value

    @property
    def resolution(self):
        return self.height * self.width

s = Screen(1024.6,768)      #不是整数,执行到这里会报错
print(s.resolution)
assert s.resolution == 786432, '1024 * 768 = %d ?' % s.resolution

分析:
@property把方法变为属性来使用。比如width方法有@property和@width.setter两块语句控制,直接套这个模板就好了。如果没有@setter语句,则表示属性为只读(比如resolution)。

3. 多重继承

  • 如果多个父类有重复的成员方法,那么子类继承的应该是参数的第一个:
class Person(object):
    def run(self):
        print('running man!')

class Dog(object):
    def run(self):
        print('running 汪!')

class Monster(Dog, Person):
    pass

xueFengSaiSai = Monster()
xueFengSaiSai.run()     # 输出应该是:running 汪!

4. 定制类

http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319098638265527beb24f7840aa97de564ccc7f20f6000

5. 枚举类

http://www.cnblogs.com/ucos/p/5896861.html

6. 元类

http://blog.jobbole.com/21351/?repeat=w3tc

正则表达式

  • 正则表达式的自由度高,实现方式非常复杂,一些简单的操作可以参考:廖雪峰的正则表达式教程。使用正则表达式一定要先导入re模块。
  • 最基本的函数就是检测匹配结果:
import re
test = '用户输入的字符串'
if re.match(r'正则表达式', test):
    print('ok')
else:
    print('failed')
  • 还有一个常用的是分组函数,分组有贪婪匹配和非贪婪匹配(项的后面带加号):
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'

最近开始偷懒了,python3没有继续往下学,后续更新敬请期待吧~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值