什么是类?

  在python中,把具有相同属性和方法的对象归为一个类(class)。类是对象的模板或蓝图,类是对象的抽象化,对象是类的实例化。类不代表具体的事物,而对象表示具体的事物。

类的创建

class Foo:
def bar(self):
pass

第一行定义了类名:语法是class 后面紧接着类的名字,这样来定义一个类。(Ps:类的名字,首字母,有一个不可文的规定,最好是大写,这样需要在代码中识别区分每个类。)
第二行开始是类的方法,大家看到了,和函数非常相似,但是与普通函数不同的是,它的内部有一个“self”,参数,它的作用是对于对象自身的引用。

类的特点

  1. 类对象是多态的:也就是多种形态,这意味着我们可以对不同的类对象使用同样的操作方法,而不需要额外写代码。
  2. 类的封装:封装之后,可以直接调用类的对象,来操作内部的一些类方法,不需要让使用者看到代码工作的细节。
  3. 类的继承:类可以从其它类或者元类中继承它们的方法,直接使用。

1. 类的封装

  对象里封装的是一些属性,而对象的方法封装在原类里,因此,当需要在其他脚本或模块中,利用其他脚本或模块的对象时,需要先导入原模块或者类。比如我在脚本(1)中定义了A对象,并且通过pickle的方式存储到文件中,当在脚本(2)需要通过pickle载入文件时,需要先import 脚本1中的类,否则会提示找不到原类。

  类的封装可以封装类的属性和类的方法,也可以在对象中封装对象。比如:

class Foo:
def __init__(self, name, age): #将name和age属性,封装到类中
self.name = name
self.age = age def speak(self, word): # 将speak方法封装到类中
print("%s say %s" % (self.name, word)) F = Foo(name='诸葛亮', age=18)
F.speak('hello')
out: 诸葛亮 say hello

上边的__init__和self是什么鬼?

  self是Python的类在实例化的时候,自动传值的东西,代表对象本身。多个对象,则self会在不同对象调用的时候,代表不同对象。

  而__init__是类的构造方法,在类进行实例化的时候会自动执行。

2. 类的继承

  类的继承就是可以从其他类中继承其他类的方法来使用。

class Human:
def __init__(self):
self.sex = ['man', 'woman'] def eat(self):
print("Human can eat, for example: %s" % self.name) class Man(Human):
def __init__(self, name, age): #将name和age属性,封装到类中
self.name = name
self.age = age def speak(self, word): # 将speak方法封装到类中
print("%s say %s" % (self.name, word)) F = Man(name='诸葛亮', age=18)
F.eat() # 调用了父类的eat方法
out:
Human can eat, for example: 诸葛亮

  其中Man类是Human类的子类,也叫做派生类。

  Human是Man类的父类,也叫做基类。

上边的代码实现了简单的继承,且继承关系简单,只有一个父类, 因此属于单继承。另外也有多继承,即从多个父类继承。

  在使用多继承的时候, 子类调用父类的方法,如果多个父类无交集,会采用从下到上,从左到右的原则进行匹配。如果多个父类有交集,则采用从下到上, 直至交集前,然后从左到右进行匹配。这种方法叫做“广度优先”。

  这里的从左到右是指,继承的先后, 比如Foo(Left, Right),那么Left类就是左,优先进行向上查找。

     从下到上是指,从Foo类开始查找,然后查找Left类,然后查找Left类的父类直至交集前的最后一层父类。图示如下:

             

3. 类的多态

   在Python用谈多态没有多大意义,多态的概念是应用于Java和C#这一类强类型语言中。在Java中,在类定义的时候,已经定义好了参数输入的类型,这与Python中是不同的。但是为了在Java中,支持Python中这样多种形态的参数输入形式,就有了多态的用法。它的实现是基于继承来实现的,用Python伪代码来表示如下:

class A:
pass class B(A):
pass class C(A):
pass # 要求arg必须是A类型
def func(arg):
pass #使用继承的话,就可以按照如下的方式使用
obj1 = B()
obj2 = C() # 这样的话,obj1和obj2就可以作为多态参数输入
func(obj1)
func(obj2)

多态python版

4. Python2 类中的多继承

  在上边已经介绍了Python3 中类的多继承为“广度优先”,那么在Python2中呢?

  对于经典类,Python2中的继承为“深度优先”。

  对于新式类,Python2中的继承为“广度优先”。

  上边的两句话怎么理解呢?那么什么是新式类,什么是经典类?

       其实很简单,新式类和经典类的区别,在书写的时候就能看出来,经典类:class A:....    ; 新式类: class A(object)。可以看出,二者区别就是创建的时候有没有继承自object.

  如何用代码测试,请看如下代码

 class A:
def f1(self):
print('A') class B(A):
def f1(self):
print('B') class C(A):
def f1(self):
print('C')
class D(B):
def f1(self):
print('D') class E(C):
def f1(self):
print('E') class F(D, E):
def f1(self):
print('F')

  上边我定义了一种继承关系。测试步骤如下:

1. 创建F对象

obj = F()

2. 循序渐进调用对象方法

obj.f1()

  每次调用obj.f1()都会打印出当前调用的是那个类中的f1方法。接下来修改对应类中的f1函数名,让f1方法在当前类中无法找到,这样就会触发子类去父类中去查找f1方法。多次尝试之后,可以得出如下的继承顺序图,从而验证了,经典类的多继承关系是深度优先!图示如下:

            

  Python2 关于新式类的多继承关系,测试方法同上,最终结果表明:新式类的继承是“广度优先”。图示如下:

             

Python菜鸟之路:Python基础-类(1)——概念的更多相关文章

  1. Python菜鸟之路:Django 路由补充1:FBV和CBV - 补充2:url默认参数

    一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...

  2. python学习之路-day2-pyth基础2

    一.        模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...

  3. Python学习之路-Day2-Python基础2

    Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...

  4. python学习之路-day1-python基础1

    本节内容: Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else ...

  5. Python学习之路-Day1-Python基础

    学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...

  6. PYTHON学习之路_PYTHON基础(8)

    学习内容: Python模块介绍 1.经典类 or 新式类 2.抽象接口 3.静态方法.类方法.属性方法 4.反射 5.异常处理 6.socket编程初识 7.用socket实现get.put文件等功 ...

  7. PYTHON学习之路_PYTHON基础(1)

    学习内容: 1.Python介绍 2.Python程序初接触和变量 3.Python用户交互 4.Python数据类型 5.Python循环if...(elif)...else 6.Python循环w ...

  8. Python学习之路-Day2-Python基础3

    Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...

  9. Python菜鸟之路:Django Admin后台管理功能使用

    前言 用过Django框架的童鞋肯定都知道,在创建完Django项目后,每个app下,都会有一个urls.py文件,里边会有如下几行: from django.contrib import admin ...

  10. Python菜鸟之路:Django 路由、模板、Model(ORM)

    Django路由系统 Django的路由系统让Django可以根据URI进行匹配,进而发送至特定的函数去处理用户请求.有点类似nginx的location功能. Django的路由关系分为三种:普通关 ...

随机推荐

  1. [转载]JAVA调用Shell脚本

    FROM:http://blog.csdn.net/jj12345jj198999/article/details/11891701 在实际项目中,JAVA有时候需要调用C写出来的东西,除了JNI以外 ...

  2. javascript另类写法

    今天来介绍一下javascript不一样的写法,很简单哦. 1.当条件成立时执行a方法,当条件失败是执行b方法 通常我们会这样写: var result; if(isOk){ result=funA( ...

  3. hdu 1030 Delta-wave(数学题+找规律)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1030 Delta-wave Time Limit: 2000/1000 MS (Java/Others ...

  4. Java过滤器(Filter)与SpringMVC拦截器(Interceptor)之间的关系与区别

    过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤 ...

  5. 如何Tomcat注册成系统服务

    1.开始->运行(windos+r)中敲cmd,DOS界面2.cd到tomcat的bin目录下3.运行命令service.bat install      这里可以指定注册服务的名字,然后就可以 ...

  6. Laravel之Session

    一.配置 Session 配置文件位于config/session.php .默认情况下,Laravel 使用的session 驱动为文件驱动,这对许多应用而言是没有什么问题的.在生产环境中,你可能考 ...

  7. Android_编程规范与经常使用技巧

    一.Android编码规范 1.java代码中不出现中文,最多凝视中能够出现中文 2.局部变量命名.静态成员变量命名 仅仅能包括字母,单词首字母出第一个外.都为大写,其它字母都为小写 3.常量命名 仅 ...

  8. rabbit mq 安装

    不知道为什么上不去erlang的官网,所以只能到中文社区来下载了. http://www.cnerlang.com/ 我下载的是下面这个版本 http://download.cnerlang.com/ ...

  9. 安装Linux centos 时编辑选项

    将第上一步选择编辑之后出来的文字修改为:>vmlinuz initrd=initrd.img linux dd quiet 这里注意了:网上很多文章都说这一步改成“>vmlinuz ini ...

  10. mysql学习笔记(编辑中)

    1.LAST_INSERT_ID()依赖于当前服务器会话中自动产生的序列编号.同时括号中也可以赋值更新数据,eg: update test set id = last_insert_id(id+10) ...