python深入理解类和对象

1,鸭子类型和多态

当看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那这只鸟就是鸭子

是不是比较混乱,看个例子:

# -*- coding:UTF-8 -*-
__autor__ = ‘zhouli‘
__date__ = ‘2018/11/14 20:46‘

class Cat:
    def say(self):
        print(‘iam a cat‘)

class Dog:
    def say(self):
        print(‘iam a dog‘)

class Duck:
    def say(self):
        print(‘iam a duck‘)

animal_list = [Cat, Dog, Duck]
for animal in animal_list:
    animal().say()

结果如下:

iam a cat
iam a dog
iam a duck

在这个地方三个类实现了同一个方法,这样就是一种多态,什么叫鸭子类型呢,就是所有类都实现共同的方法,所有的方法名称都一样,这样就是鸭子类型

2,类的三个方法:

class Date:
    # 构造函数
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tomorrow(self):
        self.day += 1

    @staticmethod
    def parse_from_string(date_str):
        year, month, day = tuple(date_str.split("-"))
        return Date(int(year), int(month), int(day))

    @staticmethod
    def valid_str(date_str):
        year, month, day = tuple(date_str.split("-"))
        if int(year) > 0 and (int(month) > 0 and int(month) <= 12) and (int(day) > 0 and int(day) <= 31):
            return True
        else:
            return False

    @classmethod
    def from_string(cls, date_str):
        year, month, day = tuple(date_str.split("-"))
        return cls(int(year), int(month), int(day))

    def __str__(self):
        return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)

if __name__ == "__main__":
    new_day = Date(2018, 12, 31)
    new_day.tomorrow()
    print(new_day)

    # 2018-12-31
    date_str = "2018-12-31"
    year, month, day = tuple(date_str.split("-"))
    new_day = Date(int(year), int(month), int(day))
    print(new_day)

    # 用staticmethod完成初始化
    new_day = Date.parse_from_string(date_str)
    print(new_day)

    # 用classmethod完成初始化
    new_day = Date.from_string(date_str)
    print(new_day)

    print(Date.valid_str("2018-12-32"))

所谓静态方法就相当于将需要外部调用的方法集成到类的内部,将命名空间并入到类中

类方法相比静态方法,不在需要硬编码了

实例方法就很简单了,使用实例+方法+()即可

3,super函数:

先看一个简单的例子:

# -*- coding:UTF-8 -*-
__autor__ = ‘zhouli‘
__date__ = ‘2018/11/17 21:18‘

class A:
    def __init__(self):
        print(‘A‘)

class B(A):
    def __init__(self):
        print(‘B‘)
        # super(B, self).__init__()  # python2的用法
        super().__init__()

# 既然已经重写了B的构造函数,为什么还要去调用super
# super到底执行顺序是什么
if __name__ == ‘__main__‘:
    b = B()

打印结果如下:但是我们得思考2个问题,①既然已经重写了B的构造函数,为什么还要去调用super

② super到底执行顺序是什么

# -*- coding:UTF-8 -*-
__autor__ = ‘zhouli‘
__date__ = ‘2018/11/17 21:18‘

class A:
    def __init__(self,user,name):
        print(‘A‘)
        self.user = user
        self.name = name

class B(A):
    def __init__(self,user,name):
        self.user = user
        print(‘B‘)
        super().__init__(name=name)

if __name__ == ‘__main__‘:
    b = B()

可以看到B类中继承A类中,如果定义父类中的部分方法,所以为了节省代码,因此采用super

super函数并不是简单的调用父类的方法,先看代码

# -*- coding:UTF-8 -*-
__autor__ = ‘zhouli‘
__date__ = ‘2018/11/17 21:18‘

class A:
    def __init__(self):
        print(‘A‘)

class B(A):
    def __init__(self):
        print(‘B‘)
        super().__init__()
class C(A):
    def __init__(self):
        print(‘C‘)
        super().__init__()
class D(B,C):
    def __init__(self):
        print(‘D‘)
        super().__init__()

if __name__ == ‘__main__‘:
    D = D()

D回去调用父类的函数,因为B在C之前,所以会有限调用

结果如下:但是注意到B在调用super之后打印的是C,而不是A

如果super是简单调用父类的构造函数的话,那么久不成立了

为什么会打印出这样的结果呢?

因为super是执行D的__mro__

print(D.__mro__)
(<class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>)

这两个数据顺序是保持一致的!

4,Mixin继承混合模式(除非万不得已,不要使用多继承)

Mixin其实和普通的多继承是本质一样的,但是Mixin有两个特点:

①  Minin里面功能比较单一,尽量简化

②  不和我们真正的类一样,不和基类关联,可以和任意基类组合,基类不和Mixin关联就能初始化成功,Minin只是定义了一个方法

③  Minin中不要使用super的方法,因为super会根据mro算法去调用他的方法,因为尽量不要和基类关联

④  命名尽量使用Mixin结尾(约定俗成)

class GoodsListViewSet(CacheResponseMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    """
    商品列表页, 分页, 搜索, 过滤, 排序
    """
    # throttle_classes = (UserRateThrottle, )
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    # authentication_classes = (TokenAuthentication, )
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = GoodsFilter
    search_fields = (‘name‘, ‘goods_brief‘, ‘goods_desc‘)
    ordering_fields = (‘sold_num‘, ‘shop_price‘)

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.click_num += 1
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

在这个类中,一个类可以完成商品列表页, 分页, 搜索, 过滤, 排序,

class ListModelMixin(object):
    """
    List a queryset.
    """
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

5,上下文管理器:

#上下文管理器协议
class Sample:
    def __enter__(self):
        print ("enter")
        #获取资源
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        #释放资源
        print ("exit")
    def do_something(self):
        print ("doing something")

with Sample() as sample:
    sample.do_something()

上下文如果使用with语句就必须在类中定义这个两个方法

那如何简化这个上下文管理器呢?

import contextlib

@contextlib.contextmanager
def file_open(file_name):
    print("file open")
    yield {}
    print("file end")

with file_open("bobby.txt") as f_opened:
    print("file processing")

在python中提供了一个contextlib模块

在上面的__enter__中的所有代码全部在yield之前操作

在yield之后是原来的__exit__方法全部放在里面

当然函数的上方必须要加上装饰器@contextlib.contextmanager

原文地址:https://www.cnblogs.com/zhoulixiansen/p/9961088.html

时间: 2024-10-31 09:06:02

python深入理解类和对象的相关文章

&lt;python&gt;模块、类、对象

Python 是一种“面向对象编程语言(Object Oriented Programming Language)”.这个说法的意思是说, Python 里边有一种叫做 class 的结构,通过它你可以用一种特殊的方式构造你的软件.通过使用 class(类),你可以让你的程序架构更为整齐,使用起来也会更为干净——至少理论上应该是这样的. 现在我要教你的是面向对象编程的起步知识,我会用你学过的知识向你介绍面向对象编程.类.以及对 象.问题是变相对象编程(简称OOP)本身就是个奇怪的东西,你只有努力

简述Python中的类与对象

Python中的类 类的定义 示例: class Person: country = "China" def __init__(self, name, age): self.name = name self.age = age def speak(self, word): print(word) 其中 country 是类属性,即 Person类 的静态属性,speak() 为 Person类的函数属性,即类的动态属性~ 类的实例化 对上述示例的类进行实例化: >>>

Python 中的类与对象 初认识

一:类的声明 1类的关键字: 从第一天第一个项目起我们就接触过关键字,比如False True is not None return for while elif else import等等,这是语言中内定的一个语法规则吧,通过关键字告诉电脑下面一个字母或一段 代码是什么,要用来干什么,告诉电脑怎么以哪种规则去用. 而class就是类的关键字,告诉系统我要定义一个类了.让系统用理解类的规则来理解我下面 的一些代码.没有关键字来声明一下,系统就不知道下面的代码是什么. 2.标识符: 标识符就是用来

Java笔记十五.深入理解类和对象(2)

类是对某一类事务的描述,是抽象的.概念上的定义:对象是实际存在的该类事务的个体,因而也称实例.可见,类描述了对象的属性和对象的行为,一个类可以对应多个对象. 一.对象 1.new关键字 在Java编程中,我们通过使用new关键字和想要创建对象的类名来实例化一个类的对象.实例化对象作用,是为对象分配内存,由new操作符根据构造方法决定新建对象分配多大的内存来存储对象.new操作符需要一个参数,就是类的构造方法,构造方法是用于初始化对象的特别方法.new操作符为对象分配内存后将调用类的构造方法确定对

Python 面向对象(创建类和对象,面向对象的三大特性是指:封装、继承和多态,多态性)

概念:                                                                                                                                                     ·        面向过程:根据业务逻辑从上到下写垒代码 ·        函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 ·        面向对象:对函数进行分类和封装,

python中的类和对象,属性和方法

一.面向对象的概述面向对象是一种描述业务问题.设计业务实体和实体之间关系的方法二.类和对象1.类和对象得区别:类是对客观世界中事物得抽象,而对象是类实例化后的实体   例如:汽车模型就是一个类,制造出来的每辆汽车就是一个对象2.类的定义:   (1)python使用class关键字定义一个类,类名的首字母一般要大写:       例如: class Student: #定义了一个Student类   (2)类的主体由一系列的属性和方法组成       例如: class Fruit: #定义一个

初步理解类和对象

对于初学者来说,对象和类往往和容易搞混. 比如举例:我想买个电视,那么电视是类还是对象?单身狗来说,媳妇是类还是对象?我是类还是对象?等等. 先看一个解释: 类是对象的抽象,对象是类的具体实例. 类是抽象的,并不存在,用计算机语言讲就是不占用内存.而对象是具体的,占有内存空间. 最后用两个例子说明一下他们的关系:例如:类就是水果,对象就是苹果.又比如“人类”就是一个类,那么具体的某个人“张三”就是“人类”这个类的对象,而“名字.年龄”等信息就是对象的属性,人的动作比如“吃饭.穿衣”等就是对象的方

Java笔记十四.深入理解类和对象(1)

Java是一种完全面向对象的编程语言(C是面向过程).所谓面向对象编程(OOP),即是一种编程风格,它通过给程序中加入扩展语句,把函数"封装"进编程所必需的"对象"中.OOP 达到了软件工程的三个主要目标:重用性.灵活性和扩展性.其实,面向对象就是把一切东西看成一个个对象,比如人,车,面包,等等,然后把这些对象拥有的属性变量,比如年龄,民族,工作地点,变质期,寿命,还有操作这些属性变量的函数(方法)打包成一个类来表示,这个类的一个抽象就是一个对象.在Java程序中,

python中的类和对象

类和对象 1. 类和对象和概念 类:共性事物的抽象,是对某一类具有共同事物的描述,是具有相同属性和方法的集合 对象:类的实例,是共性事物的一个体现,是这类事物中的每个个体 2. 总结: 类是对象的模板,对象是类的实例 3. 创建类的语法 class Math: #类名一般首字母大写 a = 4 #属性 b = 5 def add(self): c = self.a + self.b return c 注意: 类名一般首字母大写,比如class User ,其中class是关键字 类里面包含属性(