python 面向对象

面向对象

面向对象 vs 面向过程

面向对象着重谁去做
面向过程着重做什么

类和对象

类:描述具有相同属性或者方法的集合
对象/实例: 具体的摸个事务,实实在在的一个实例
实例化:创建一个对象的实例
属性:对象的描述信息 -变量
方法:对象的方法 -函数

面向对象的三大特征

1.封装
2.继承
3.多态

类的命名:驼峰式命名 HunanAtm

python2 vs python3
python2 经典类和新式类
python3 只有新式类
 新式类显式继承object
 反之为经典类
 • 经典类
    • 所有的类都是classobj类型,而类的实例都是instance类型。
    • 类与实例只有通过__class__属性进行关联
• 新式类(c3算法)
    • 类实例的类型是这个实例所创建自的类(通常是和类实例的__class__相同)
c3算法
        首先将自身类加入本序列,然后对继承序列的元素依次判断
        若某个元素不在其它序列,或者它是所有继承序列的第一个,那么把这个元素提取到本序列
class A:
    def test(self):
        print("from A")

class B(A):
    def test(self):
        print("from B")

class C(A):
    def test(self):
        print("from C")

class D(B):
    def test(self):
        print("from D")

class E(C):
    def test(self):
        print("from E")

class F(D, E):
    def test(self):
        print("from F")

f = F()
f.test()

# 经典类: F --> D --> B --> A -->E -->C
# 新式类: F --> D --> B --> E --> C --> A

类空间和实例空间

类创建的时候会生成类空间
实例化对象就会生成实例空间,不同实例之间,空间都是独立的
实例查找属性方法的时候,先会去实例空间查找,找不到就去类空间查找
类空间找不到,就去父类空间找

实例可以访问到类以及父类空间
类访问不到实例空间

实例可以访问类空间属性,但是改变不了类空间属性

__init__方法

实例对象的构造方法(初始化方法)
实例化对象的时候 自动调用__init__方法

__new__方法

创建实例的方法,一般情况下不需要重写

小结

__new__是创建实例的方法
__init__是对创建好的实例进行初始化工作的方法

    __new__方法必须要传入一个参数(cls),代表当前类
    __new__必须返回一个实例化对象
    __init__的self就表示__new__返回的实例,__init__对这个实例进行初始化工作
    子类没有定义__new__,就会去找父类的__new__
    新式类才有__new__
    如果实例化对象和本身class不一致,__init__就不执行

单例模式

无论实例化多少次,都返回同一个对象实例 重写__new__

class Danli:
    instance = None
    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            # cls.instance = super().__new__(cls)
            cls.instance = object.__new__(cls)  #
        return cls.instance

# 创建多个对象
dan1 = Danli()
print(dan1)
dan2 = Danli()
print(dan2)

dan1.area = "hunan"
print(dan1.area)
# del dan1.area
# print(dan1.area)
# print(Danli.instance)
# Danli.model = 1
# Danli.model = 2
# print(Danli.model)
#删除实例属性  del

self详解

self 就代表实例本身

self不必写成self  它就是形参名字,一般约定俗称写成self
class Person():
    name = "sc"
    def info(this):
        print(f'i am {this.name}')
        print(this)
        print(this.__class__)

p = Person()
p.info()

self可以不写
class Person():
    name = "sc"
    def info(this):
        print(f'i am {this.name}')
        print(this)
        print(this.__class__)

    def info2():
        print("this is info2")

p = Person()
# p.info2()  #==>Person.info2(p)
Person.info2()

类的继承

#python实现链表的反转
class Node(object):
    def __init__(self, value=None, next=None):
        self.value = value
        self.next = next

    @staticmethod   #静态方法
    def reverse(head):
        cur_node = head  # 当前节点
        new_link = None  # 表示反转后的链表
        while cur_node != None:
            tmp = cur_node.next  # cur_node后续节点传递给中间变量
            cur_node.next = new_link  # cur_node指向new_link
            new_link = cur_node  # 反转链表更新,cur_node为新的头结点
            cur_node = tmp  # 原链表节点后移一位
        return new_link


link = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))
# print(link.value)
# print(link.next.value)
# print(link.next.next.value)
# print(link.next.next.next.value)
root = Node.reverse(link)
while root:
    print(root.value)
    root = root.next

多态

python里不支持多态, python处处是多态

接口

def pay(obj): #python里崇尚鸭子类型,不管obj数据什么类型,只管obj有没有pay方法
    obj.pay()

pay(zhi)
pay(wei)

python中不支持多态

语法上的多态 不需要额外实现多态的代码
按照多态的严格语法 不属于多态(父类作为参数,传递子类对象)

python里处处是多态 python是一个动态类型语言,崇尚鸭子类型,本身就实现了多态

不关心对象是什么类型,到底是不是鸭子,只关心行为

属性

属性: 对象描述信息
静态属性 – 类属性
普通属性 – 实例属性


方法

实例方法
静态方法
类方法

python中的下划线

_max 保护属性
__min 私有属性,类内部访问,子类都不能访问,对象也不能访问的

python的私有是一种伪私有,是在类的内部对双下划綫的变量名做了一层转换
__min -> _类名__max
常见的私有属性
__name__ 类名
__class__ 对象所属的类
__modoule__ 所在模块
__doc__ 文档

魔术方法

魔术方法不需要手动调用,在一定的场景下自动执行,有特殊含义的方法

## 构造方法
__new__
__init__
## 析构方法
__del__
## 调用方法
__call__ 实例化之后将对象当做函数调用
只有可调用对象callable才有的方法
## 其他
__str__:用户
__repr__:程序员

__getitem__
__setitem__
__delitem__

python自省

• getattr(obj, ‘name’):
获取成员 • 根据字符串去获取obj对象里的对应的方法的内存地址
• hasattr(obj, ‘name’):
检查是否含有成员 • 判断一个对象obj里是否有对应的name_str字符串的方法
• setattr(obj, ‘age’, 18): 设置成员
• delattr(obj, ‘name’): 删除成员
脚本传参的方式
1.sys.argv
2.getopt

    import getopt
    import sys

    opts, args = getopt.getopt(sys.argv[1:], 'h:i:', ['help', 'input='])
    print(opts)
    print(args)

3.argparse
4.fire

元类

元类:创建类的类称为元类
type是最上层的元类
-> 表示期望传入的数据类型,非强制
使用type函数创建对象

name:str  期望name传入一个str类型
->None   期望函数有一个None返回值
def init(self, name:str)  ->None:
    self.name = name
def eat(self):
    print("i am eating....")

#第一个参数  类名
#第二个参数元组类型 显示是继承关系
#第三个参数是字典  设置属性和方法
Animal = type("Animal", (object,), {"species":'animals','__init__':init, 'eat':eat})

a1 = Animal("sc")
a1.eat()
print(a1.species)

元类一般用于拦截类的创建
自定义元类

class MyMate(type):
    def __new__(cls, name, bases, attrs):
        if "foo" not in attrs:
            raise TypeError("必须设置foo属性")
        attrs["test"] = "mymate"
        return type.__new__(cls, name, bases, attrs)

class A(metaclass=MyMate):
    #pass
    foo = "foo!"

a = A()
print(a.test)

python面向对象有两种关系
1、继承关系 object是所有类的父类,是最顶层的类
2、创建关系 实例与类的关系 type是最顶层的类

抽象基类

抽象基类 定义了接口规范,子类必须实现抽象基类父类里的抽象方法
抽象基类不能实例化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值