第七篇 Python面向对象
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就相当于制造飞机时的图纸,是一个模板,是负责创建对象的。
对象是由类创建出来的一个具体存在,可以直接使用,由哪个类创建出来的对象,就拥有在那个类中定义的属性和方法,对象就相当于用图纸制造的飞机,在程序开发中,先有类,然后再有对象。
1.创建类和对象
#创建类:class为创建类的关键字,Dog为类名,self为方法的特殊参数,必填
class Dog:
#类中定义的函数为方法
def eat(self):
print("狗吃饭")
def run(self):
print("狗奔跑") #根据Dog类创建对象dog
dog = Dog()
说明:
1.类名表示一类事物的名字,满足大驼峰命名法(每一个单词的首字母大写,单词与单词质检没有下划线);属性表示一类事物具有什么样的特征;方法表示一类事物具有什么样的行为。
2.使用内置函数dir传入标识符/数据,可以查看对象内的所有属性和方法。
def demo():
pass print(dir(demo)) -------输出结果--------
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
3.Python中self表示当前对象,当前正在操作的对象,而不是当前类,当某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以我们只需要传递后面的参数即可。
class Person: def eat(self): # 类中所有def定义的方法,参数都要带self,而且要放在第一位
print("人吃饭......") person = Person()
person.eat()
4.当使用类名()创建对象时,会自动执行以下操作:为对象在内存中分配空间,即创建对象;为对象的属性设置初始值,即调用初始化方法,这个初始化方法就是__init__方法,该方法是对象的内置方法。
__init__方法是专门用来定义一个类具有哪些属性的方法,在__init__方法内部使用self.属性名=属性的初始值,就可以定义属性,定义属性后,再使用类创建的对象,都会拥有该属性。
class Person: def __init__(self, name, age):
self.name = name
self.age = age def eat(self):
print("%s 吃饭" % self.name) person = Person("张三", 18)
person.eat()
5.内置方法__del__(对象被从内存中销毁前,该方法会被自动调用)和__str__(返回对象的描述信息,print函数输出使用)。
6.在定义属性或者方法时,在属性或者方法名前增加两个下划线,定义的就是私有属性或者方法。
在Python中并没有真正意义上的私有,在给属性,方法命名时,实际是对名称做了一些特殊处理,使得外界无法访问到,可以在所有属性或者方法前面加上_类名,即_类名__名称访问私有属性或者方法。
class Person: def __init__(self, name, age):
self.name = name
self.age = age def eat(self):
print("%s 吃饭" % self.name) def __jump(self):
print("%s 跳舞" % self.name) person = Person("张三", 18)
person.eat()
# person.__jump() 报错
person._Person__jump()
说明:_name,_name_,_name__为建议性的私有成员,不要在外部访问;__name,__name_为强制的私有成员;__name__为特殊成员,与私有性质无关,如__doc__;name_,name__没有任何特殊性,但是最好不要这样命名。
7.类的成员包括字段(实例字段,静态字段),方法(普通方法,类方法,静态方法)和属性(普通属性),其中只有普通字段的内容保存在对象中,而其他的成员,则都是保存在类中。
字段
字段分为实例字段和静态字段,他们的区别主要是在内存中保存的位置不同,实例字段属于对象,静态字段属于类。
class Province:
country = "中国" # 静态字段(类变量,定义在类中,方法之外的变量) def __init__(self, name):
self.name = name # 实例字段 province = Province("山东省")
print(province.name)
print(Province.country)
实例字段通过对象访问,静态字段通过类可以直接访问,也可以使用实例进行访问,如果是实例进行访问,首先在寻找实例字段,没有则取寻找类字段,如果还米有,则报错;如果使用实例.类变量修改类变量值后,我们通过实例.类变量实际上访问的是实例变量,类变量的值并没有修改。
In []: class Student:
...: classroom = '' # 类字段
...: address = 'shandong'
...: def __init__(self, name, age):
...: self.name = name # 实例字段
...: self.age = age
...: In []: zhang = Student('张三',) In []: li = Student('李四', ) In []: zhang.classroom # 访问的是类字段
Out[]: '' In []: li.classroom # 访问的是类字段
Out[]: '' In []: zhang.classroom = '' # 创建实例独有的字段 In []: li.classroom # 访问类字段
Out[]: '' In []: zhang.classroom # 访问实例字段
Out[]: '' In []: Student.classroom
Out[]: '' In []: del zhang.classroom In []: zhang.classroom
Out[]: '' In []: li.classroom
Out[]: '' In []: Student.classroom
Out[]: ''
方法
方法包括实例方法,静态方法和类方法,三个方法在内存中都属于类。
- 实例方法:由对象调用,至少有一个self参数,当对象调用方法时自动把对象赋值给self。
- 类方法:由类调用,至少一个cls参数,当调用方法时自动把类赋值给cls。
- 静态方法:由类调用,无默认参数。
class Demo: def ord_func(self):
print("普通方法") @classmethod
def class_method(cls):
print("类方法") @staticmethod
def static_method():
print("静态方法") demo = Demo()
demo.ord_func() # 调用普通方法
Demo.class_method() # 调用类方法
Demo.static_method() # 调用静态方法
属性
@properties装饰器可以把类的方法伪装成属性调用,即obj.func()的调用方式编程obj.func的方式。
class Demo:
# 定义属性
@property
def f(self):
return "boxiaoyuan" demo = Demo()
print(demo.f) # 调用属性
在定义属性时,只需要在普通方法的基础上添加@property即可,属性只有一个参数self。
Python的类有经典类(Python2)和新式类(Python3),新式类的属性有三种访问方式,即@property,@方法名.setter,@方法名.deleter,经典类只有一种,即在普通方法上增加@property。
# -*- coding:utf- -*- class Person: def __init__(self, name, age):
self.__name = name
self.__age = age @property
def age(self):
return self.__age @age.setter
def age(self, age):
if isinstance(age, int):
self.__age = age
else:
raise ValueError @age.deleter
def age(self):
print("删除age数据") if __name__ == '__main__':
person = Person("zhangsan", )
print(person.age)
person.age =
print(person.age)
del person.age
property()函数,是另外一种设置类属性的方法。
# -*- coding:utf- -*- class Person: def __init__(self, name, age):
self.__name = name
self.__age = age def get_age(self):
return self.__age def set_age(self, age):
if isinstance(age, int):
self.__age = age
else:
raise ValueError def del_age(self):
print("删除age数据") age = property(get_age, set_age, del_age, "年龄") if __name__ == '__main__':
person = Person("zhangsan", )
print(person.age)
person.age =
print(person.age)
del person.age
property的构造方法中有四个参数:第一个参数是方法名,调用对象.属性时自动触发执行方法;第二个参数是方法名,调用对象.属性 = xxx时自动触发执行方法;第三个参数是方法名,调用del 对象.属性时自动触发;第四个参数是字符串。
2.面向对象的三大特性
1)封装:把内容封装起来,然后进行调用
class Dog:
def __init__(self,name,age):
self.name=name
self.age=age
def eat(self):
print("狗吃饭")
def run(self):
print("狗奔跑")
def display(self):
print(self.name)
print(self.age) dog=Dog('boxiaoyuan',15)
print(dog.name)
print(dog.age)
dog.display() -------输出结果------
boxiaoyuan
15
boxiaoyuan
15
注:对于面向对象的封装来说,就是把内容通过构造函数封装到对象中,然后通过对象直接调用或者使用self间接调用。
2)继承:实现代码的重用,相同的代码不需要重复的编写。
继承的概念:子类拥有父类的所有方法和属性。
子类继承父类,可以直接享受父类中已经封装好的方法,子类中应该根据职责,封装子类特有的属性和方法。
class Animal:
def eat(self):
print("吃东西") def drink(self):
pass def run(self):
pass class Dog(Animal):
def dark(self):
print("狗叫") dog = Dog()
dog.eat()
dog.dark()
当父类的方法实现不能满足子类需求时,可以对方法进行重写(override)。
class Animal:
def eat(self):
print("吃东西") def drink(self):
pass def run(self):
pass class Dog(Animal):
def dark(self):
print("狗叫") def run(self):
print("狗跑的很快呀") dog = Dog()
dog.eat()
dog.dark()
我们都知道,在子类中如果有与父类同名的成员,则子类会覆盖掉父类里的成员,如果想要调用父类的成员,super()函数,最常见的是调用父类的实例化方法__init__()。
语法:super(子类名, self).方法名(),super传入的是子类名和self,调用的是父类的方法,需要根据父类的方法传入对应的参数。
class Animal:
def eat(self):
print("吃东西") def drink(self):
pass def run(self):
print("跑") class Dog(Animal):
def dark(self):
print("狗叫") def run(self):
super().run()
print("狗跑的很快呀") dog = Dog()
dog.run()
子类对象不能在自己的方法内部直接访问父类的私有属性和私有方法,但是子类对象可以通过父类的公有方法间接访问私有属性和私有方法。
class A:
def __init__(self):
self.__num = 12
self.num2 = 14 def __test(self):
print("父类私有方法") def test(self):
print(self.__num)
self.__test() class B(A):
def sub_test(self):
self.test() b = B()
b.sub_test()
说明:子类不重写__init__,实例化子类时,会自动调用父类定义的__init__方法,但是子类重写了__init__时,实例化子类时,就不会调用父类已经定义的__init__。
Python的类可以继承多个类,当Python的类继承了多个类时,其寻找方法的方式有两种,分别是:深度优先和广度优先。Python3中采用深度优先的方式。
如下的继承关系,寻找方法的顺序为:
class A(B, E):
pass
如下集成关系,寻找方法的顺序为:
class A(B, E):
pass
3)多态:不同的子类对象调用相同的父类方法,产生不同的结果。
class Animal: def __init__(self, name):
self.name = name def play(self):
print("动物正在玩") class Dog(Animal):
def play(self):
print("小狗正在玩") class Cat(Animal):
def play(self):
print("小猫正在玩") class Person: def __init__(self, name):
self.name = name def play_with_animal(self, animal):
print("%s正在和%s玩" %(self.name, animal.name))
animal.play() # dog = Dog("旺仔")
cat = Cat("小猫咪")
person = Person("小明")
# person.play_with_animal(dog)
person.play_with_animal(cat)
第七篇 Python面向对象的更多相关文章
- 【Python之路】特别篇--Python面向对象(进阶篇)
上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- Python【第七篇】面向对象进阶
大纲 一.面向对象高级语法 1.静态方法.类方法.属性方法 2.类的特殊成员方法 3.反射 二.异常处理 三.网络编程之socket基础 一.面向对象高级语法 1.静态方法:名义上归类管理,实际上静态 ...
- 【Python之路】第七篇--Python基础之面向对象及相关
面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查obj是否是类 cls 的对象 class Foo(objec ...
- 【python自动化第七篇:面向对象进阶】
知识点概览: 静态方法,类方法,属性方法 类的特殊方法 反射 异常处理 socket开发基础 一.静态方法:@staticmethod 只是名义上归类管理,实际上在静态方法里访问不了类或者实例中的任何 ...
- python之旅七【第七篇】面向对象之类成员
面向对象的类成员 相关知识点 一 字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Provinc ...
- python之旅六【第七篇】面向对象
面向对象三大特性 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强... 面向对象编程 ...
- Python成长笔记 - 基础篇 (七)python面向对象
三大特性: 1.封装:在类中对数据赋值.内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法 2.继承:一个类可以派生出子类,在父类中定义的属性.方法会自动被子类继承 ...
- 第七篇 python基础之函数,递归,内置函数
一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因 ...
- Python之路(第七篇)Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数
一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") ret ...
随机推荐
- git版本控制-详细操作
- git,软件帮助使用者进行版本的管理 阶段一git 命令: git init 初始化 git config --global user.email "you@example.com&qu ...
- 根文件系统的构建与分析(三)之根文件目录及最简/dev目录
根文件系统的构建与分析(三) 转载请注明 http://blog.csdn.net/jianchi88 Author:Lotte 邮箱:baihaowen08@126.com 一.FHS(Fi ...
- 基于FORM组件学生管理系统【中间件】
目的:实现学生,老师,课程的增删改查 models.py from django.db import models # Create your models here. class UserInfo( ...
- C#递归所以部门展示到TreeView
C#递归所以部门展示到TreeView 1.首先是数据库表的设计 新建一张部门表:TestUser表 1.ID自增int主键 2.DeptName:nchar(10)3.DeptCode:nchar( ...
- 由ffmpeg中avformat模块中的 URL_SCHEME_CHARS 看 strspn( ) 的妙用
在ffmpeg的avformat 模块中avio.c 对 URL_SCHEME_CHARS 的定义: #define URL_SCHEME_CHARS \ "abcdefghijklmnop ...
- 【原创】1. MYSQL++简介
MYSQL++是对于MYSQL C API的C++完全包装. MYSQL++能够至少做如下几件事情 1. 连接数据库 通过TCP连接数据库 通过WINDOWS命名管道连接数据库 UNIX域SOCKET ...
- NFA/DFA算法
1.问题概述 随着计算机语言的结构越来越复杂,为了开发优秀的编译器,人们已经渐渐感到将词 法分析独立出来做研究的重要性.不过词法分析器的作用却不限于此.回想一下我们的老师刚刚开始向我们讲述程序设计的时 ...
- LoadRunner 关联和集合点、检查点
1)关联的定义 很多时候,当时录完之后,没有问题.过一段时间再跑脚本,就不会成功.比如session,过期了,再一次使用,就会出错.这个时候,需要在每次访问的时候动态的拿到session,这种情况就需 ...
- 【转】http 缓存
原文地址:https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-c ...
- 在Win7 64位电脑上安装Sql Server 2008 R2 Express
安装环境说明: 操作系统:Win7 64位 英文版 安装步骤: 1.准备安装文件 下载网址:https://www.microsoft.com/zh-CN/download/details.aspx? ...