广告设计网站建设怎么做,网站建设网页设计,成都市网站备案,室外绿化工程施工方案久久建筑网文章目录1. 面向对象编程类和实例访问限制继承和多态type()isinstance()dir()实例属性和类属性2. 面向对象高级编程\_\_slots\_\_property多重继承定制类枚举类元类1. 面向对象编程
Object Oriented Programming
简称 OOP#xff0c;一种程序设计思想#xff0c;以对象为程…
文章目录1. 面向对象编程类和实例访问限制继承和多态type()isinstance()dir()实例属性和类属性2. 面向对象高级编程\_\_slots\_\_property多重继承定制类枚举类元类1. 面向对象编程
Object Oriented Programming
简称 OOP一种程序设计思想以对象为程序基本单元一个对象包含数据和数据的操作方法
面向对象的设计思想来自自然界的类Class和实例Instance抽象出 Class根据 Class 创建 Instance抽象程度比函数高既包含数据又包含操作数据的函数
数据封装、继承、多态是面向对象的三大特点
类和实例
Class 是抽象的模板是创建 Instance 的模板 class Student(object): # 定义类
... pass
...s1 Student() # 创建实例s1.name Aurelius # 实例属性绑定s1.name
AureliusPython 允许对实例绑定任何数据即使一个类的两个实例他们拥有的变量名称都可能不同
创建实例时强制绑定属性
class Student(object):def __init__(self, name, score):self.name nameself.score score和普通函数相比类中定义的函数第一个参数永远是实例变量 self且调用时不用传值self 指向创建的实例本身
数据封装
通过实例函数访问实例的数据不直接从外部访问这些数据
访问限制
限制外部代码对实例内部一些属性和方法的访问可以加强代码的健壮性
Python 没有任何强制机制限制访问权限
在 Class 定义的内部属性前加 __ 可以把属性变成私有通过 get_p(), set_p() 方法来访问这些属性
__property 被 Python 解释器自动改为 _ClassName__property
__xxx__ 在 Python 中属于特殊属性不是私有的可以被访问的
继承和多态 继承可以把父类的所有功能直接拿来子类只需要新增自己特有的方法重写覆盖父类中不适合的方法 多态是把一个子类对象赋给一个父类变量调用方法是子类实现
开闭原则
对扩展开放对修改封闭
鸭子模式
def twice_run(animal):animal.run()animal.run()class Timer(object):def run(self):print(Start ...)传入 twice_run() 的对象不必是 Animal 的子类只要有 run() 即可
因此相对静态语言动态语言Python的继承不是那么必要
type()
获取对象类型
类型类型常量对象intint123strstr‘123’函数types.FunctionTypedef fn(): pass内建函数types.BuiltinFunctionTypeabs匿名函数types.LambdaTypelambda x: x生成器types.GeneratorType(x for x in range(10))
isinstance()
判断是否指定类型或指定类型元组中的一个 isinstance(x, t) # x 是对象t 是类型t 可以是多个类型组成的一个 tuple 对象dir()
获取对象的所有属性和方法
len()
实际是调用了对象的 __len__() 方法因此按照鸭子类型自己的类只要实现了 __len__()也可以使用 len(myObj)
getattr(obj, pname)
获取对象的指定属性或方法也可以传第 3 个参数作为默认值
setattr(obj, pname, pvalue)
设置对象指定属性的值
hasattr(obj, pname)
判断对象是否存在指定名称的属性或方法
可以确定存在而直接访问的属性或方法就不要使用getattr因此可以通过hasattr判断属性或方法是否存在
实例属性和类属性
通过实例变量或self变量绑定实例属性
通过类本身绑定的是类属性类属性归类所有但类的所有实例都可以访问到 class Student(object):
... name Student
...s Student()print(s.name)
Studentprint(Student.name)
Students.name Aureliusprint(s.name)
Aureliusprint(Student.name)
Studentdel s.nameprint(s.name)
Student相同名称的实例属性将屏蔽类属性当查找到对应名称的实例属性时即使存在同名类属性也不会被查找到当删除实例属性后可以再次访问到类属性
2. 面向对象高级编程
__slots__
动态绑定方法
给Instance绑定方法只对当前Instance有效
class Student(object):passs Student()def set_age(self, age):self.age agefrom types import MethodType
s.set_age MethodType(set_age, s)
s.set_age(25)给Class绑定方法对所有Instance有效
def set_score(self, score):self.score scoreStudent.set_score set_score
s.set_score(100)使用 __slots__
用来限制 class 实例可以添加的属性包括Class定义中绑定的属性
class Student(object):# tuple定义允许绑定的属性名称__slots__ (name, age)__slots__只对当前类有效对子类无效若子类也定义了__slots__有效范围是自身加父类的范围
不定义__slots__的类相当于其有效范围是任意属性
property
把一个getter方法变成属性同时创建另一个装饰器pname.setter负责把另一个setter方法变成属性赋值
class Student(object):propertydef birth(self):return self._birthbirth.setterdef birth(self, value):self._birth value# 只读属性propertydef age(self):return 2020 - self._birth多重继承
Python 允许使用多重继承一个子类可以同时继承多个父类的所有功能
MixIn
除了继承自主线还额外混入其他类的功能这种设计叫MixIn
定制类
通过一些__xxx__属性定制类
__str__
返回给用户看到的字符串实例的打印结果
__repr__
返回实例调式值显示结果
__iter__
将Class实例变成一个迭代器需要实现__next__()方法for 循环会不断调用迭代对象的__next__()
class Fib(object):def __init__(self):self.a, self.b 0, 1def __iter__(self):return selfdef __next__(self):self.a, self.b self.b, self.a self.bif self.a 1000:raise StopIteration()return self.a__getitem__
通过索引器或者切片读取实例的值时被调用
class Fib(object):def __getitem__(self, n):if isinstance(n, int):a, b 1, 1for x in range(n):a, b b, a breturn aif isinstance(n, slice):start, stop n.start, n.stopif start is None:start 0a, b 1, 1res []for x in range(stop):if x start:res.append(a)a, b b, a breturn resslice的step参数和负数值可以进一步处理
__getattr__
当调用实例不存在的属性时被调用已有的属性不会在__getattr__中查找
__getattr__可以实现完全动态的调用
class Chain(object):def __init__(self, path):self._path pathdef __getattr__(self, path):return Chain(f{self._path}/{path})def __call__(self, param):return Chain(f{self._path}/{param})def __str__(self):return self._path__repr__ __str__print(Chain().status.user(Aurelius).timeline.list)__call__
定义了__call__就可以调用实例本身__call__可以有参数
class Student(object):def __init__(self, name):return self._namedef __call__(self, text):print(f{self._name}: {text})print(Student(Aurelius)(A))类本身的调用会执行type的__call__方法
枚举类
将一组相关常量定义在一个Class中并且不可变成员可以直接比较
通过Enum调用 from enum import EnumMonth Enum(Month, (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec))for name, member in Month.__members__.items():
... print(name, , member, ,, member.value)
...
Jan Month.Jan , 1
Feb Month.Feb , 2
Mar Month.Mar , 3
Apr Month.Apr , 4
May Month.May , 5
Jun Month.Jun , 6
Jul Month.Jul , 7
Aug Month.Aug , 8
Sep Month.Sep , 9
Oct Month.Oct , 10
Nov Month.Nov , 11
Dec Month.Dec , 12通过继承Enum
from enum import Enum, uniqueunique
class Weekday(Enum):Sum 0 # 默认从 1 开始这里设置 0Mon 1Tue 2Wed 3Thu 4Fri 5Sat 6获取方式
Enum[Name]Enum.NameEnum(value)
元类
type
type函数既可以返回一个对象的类型又可以创建出新的类型
type创建class
def fn(self, nameworld):print(fHello, {name})Hello type(Hello, (object,), dict(hellofn))
h Hello()
h.hello()type() 的 3 个参数
class 的名称继承的父类元组class 的方法和其绑定函数的字典
metaclass
metaclass允许创建类或修改类可以把类看作metaclass创建的实例
定义metaclass
class ListMetaclass(type):def __new__(cls, name, bases, attrs):attrs[add] lambda self, value: self.append(value)return type.__new__(cls, name, bases, attrs)__new__()的 4 个参数依次是
当前准备创建的类对象类的名称类继承的父类元组类的方法字典
定制类
# 在 Python 解释器创建 MyList 时要通过 ListMetaclass.__new__() 来创建
class MyList(list, metaclassListMetaclass):passPython 解释器首先在当前类的定义中查找metaclass如果没有就继续在父类查找知道找到用来创建当前类metaclass隐式继承到子类 上一篇「Python 基础」函数与高阶函数 专栏《Python 基础》
PS感谢每一位志同道合者的阅读欢迎关注、评论、赞