基于python3 类的属性、方法、封装、继承实例讲解


Posted in Python onSeptember 19, 2017

Python 类

Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

对象可以包含任意数量和类型的数据。

python类与c++类相似,提供了类的封装,继承、多继承,构造函数、析构函数。

在python3中,所有类最顶层父类都是object类,与java类似,如果定义类的时候没有写出父类,则object类就是其直接父类。

类定义

类定义语法格式如下:

class ClassName:
<statement-1>
.
.
.
<statement-N>

类对象:创建一个类之后,可以通过类名访问、改变其属性、方法

实例对象:类实例化后,可以使用其属性,可以动态的为实例对象添加属性(类似javascript)而不影响类对象。

类的属性

可以使用点(.)来访问对象的属性

也可以使用以下函数的方式来访问属性:

getattr(obj, name[, default]) : 访问对象的属性

hasattr(obj,name) : 检查是否存在一个属性

setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性

delattr(obj, name) : 删除属性

Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)

__doc__ :类的文档字符串

__name__: 类名

__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

__bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)

class Person:
  "Person类"
  def __init__(self, name, age, gender):
    print('进入Person的初始化')
    self.name = name
    self.age = age
    self.gender = gender
    print('离开Person的初始化')
  def getName(self):
    print(self.name)
p = Person('ice', 18, '男')
print(p.name) # ice
print(p.age) # 18
print(p.gender) # 男
print(hasattr(p, 'weight')) # False
# 为p添加weight属性
p.weight = '70kg'
print(hasattr(p, 'weight')) # True
print(getattr(p, 'name')) # ice
print(p.__dict__) # {'age': 18, 'gender': '男', 'name': 'ice'}
print(Person.__name__) # Person
print(Person.__doc__) # Person类
print(Person.__dict__) # {'__doc__': 'Person类', '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__init__': <function Person.__init__ at 0x000000000284E950>, 'getName': <function Person.getName at 0x000000000284EA60>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__module__': '__main__'}
print(Person.__mro__) # (<class '__main__.Person'>, <class 'object'>)
print(Person.__bases__) # (<class 'object'>,)
print(Person.__module__) # __main__

类的方法

在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数。

类的专有方法:

__init__ 构造函数,在生成对象时调用

__del__ 析构函数,释放对象时使用

__repr__ 打印,转换

__setitem__按照索引赋值

__getitem__按照索引获取值

__len__获得长度

__cmp__比较运算

__call__函数调用

__add__加运算

__sub__减运算

__mul__乘运算

__div__除运算

__mod__求余运算

__pow__称方

__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法,与c++中构造函数类似。只需在自定义的类中重写__init__()方法即可。

class Person:
  def __init__(self, name, age, gender):
    print('进入Person的初始化')
    self.name = name
    self.age = age
    self.gender = gender
    print('离开Person的初始化')
  def getName(self):
    print(self.name)
# Person实例对象
p = Person('ice', 18, '男')
print(p.name)
print(p.age)
print(p.gender)
p.getName()
# 进入Person的初始化
# 离开Person的初始化
# ice
# 18
# 男
# ice

析构函数 __del__ ,__del__在对象消逝的时候被调用,当对象不再被使用时,__del__方法运行:

方法

实例方法:只能通过实例调用,实例方法第一个定义的参数只能是实例本身引用

class Myclass:
  def foo(self):
    print(id(self),'foo')

a=Myclass()#既然是实例对象,那就要创建实例
a.foo()#输出类里的函数地址
print(id(a))#输出类对象的地址

#结果地址一样

类方法:定义类方法,要使用装饰器@classmethod,定义的第一个参数是能是类对象的引用,可以通过类或者实例直用

class Myclass:
@classmethod#类装饰器
  def foo2(cls):
    print(id(cls),'foo2')
  #类对象,直接可以调用,不需要实例化
print(id(Myclass),'yy')
Myclass.foo2()#直接可以调用

静态方法:定义静态方法使用装饰器@staticmethod,没有默认的必须参数,通过类和实例直接调用

class Myclass:
@staticmethod#静态方法
  def foo3():
    print('foo3')

Myclass.foo3()#没有参数
a.foo3()
#结果foo3

类的封装

python通过变量名命名来区分属性和方法的访问权限,默认权限相当于c++和java中的public

类的私有属性: __private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。

类的私有方法:__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods

虽然python不允许实例化的类访问私有数据,但可以使用 object._className__attrName 访问属性。其实python内部私有化的实现只是将attrName属性变为了_className__attrName而已

class Demo:
  __id = 123456
  def getId(self):
    return self.__id
temp = Demo()
# print(temp.__id) # 报错 AttributeError: 'Demo' object has no attribute '__id'
print(temp.getId()) # 123456
print(temp._Demo__id) # 123456

类的继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写作括号里,基本类是在类定义的时候,在元组之中指明的。

在python中继承中的一些特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。使用super().__init__()或parentClassName.__init__()

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

语法:

派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后。

多态

如果父类方法的功能不能满足需求,可以在子类重写父类的方法。实例对象调用方法时会调用其对应子类的重写后的方法

python3.3 类与继承 小例

hon中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

class Base:
  def __init__(self):
    self.data=[]
  def add(self,x):
    self.data.append(x)
  def addtwice(self,x):
    self.add(x)
    self.add(x)

# child extends base
class Child(Base):
  def plus(self,a,b):
    return a+b

oChild=Child()
oChild.add("str1")
oChild.add(999)
oChild.addtwice(4)
print(oChild.data)
print(oChild.plus(2,3))

对象可以包含任意数量和类型的数据。

python类与c++类相似,提供了类的封装,继承、多继承,构造函数、析构函数。

在python3中,所有类最顶层父类都是object类,与java类似,如果定义类的时候没有写出父类,则object类就是其直接父类。

类定义

类定义语法格式如下:

class ClassName:
<statement-1>
.
.
.
<statement-N>

类对象:创建一个类之后,可以通过类名访问、改变其属性、方法

实例对象:类实例化后,可以使用其属性,可以动态的为实例对象添加属性(类似javascript)而不影响类对象。

类的属性

可以使用点(.)来访问对象的属性

也可以使用以下函数的方式来访问属性:

getattr(obj, name[, default]) : 访问对象的属性

hasattr(obj,name) : 检查是否存在一个属性
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性

delattr(obj, name) : 删除属性

Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)

__doc__ :类的文档字符串

__name__: 类名

__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

__bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)

class Person:
  "Person类"
  def __init__(self, name, age, gender):
    print('进入Person的初始化')
    self.name = name
    self.age = age
    self.gender = gender
    print('离开Person的初始化')
  def getName(self):
    print(self.name)
p = Person('ice', 18, '男')
print(p.name) # ice
print(p.age) # 18
print(p.gender) # 男
print(hasattr(p, 'weight')) # False
# 为p添加weight属性
p.weight = '70kg'
print(hasattr(p, 'weight')) # True
print(getattr(p, 'name')) # ice
print(p.__dict__) # {'age': 18, 'gender': '男', 'name': 'ice'}
print(Person.__name__) # Person
print(Person.__doc__) # Person类
print(Person.__dict__) # {'__doc__': 'Person类', '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__init__': <function Person.__init__ at 0x000000000284E950>, 'getName': <function Person.getName at 0x000000000284EA60>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__module__': '__main__'}
print(Person.__mro__) # (<class '__main__.Person'>, <class 'object'>)
print(Person.__bases__) # (<class 'object'>,)
print(Person.__module__) # __main__

类的方法

在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数。

类的专有方法:

__init__ 构造函数,在生成对象时调用

__del__ 析构函数,释放对象时使用

__repr__ 打印,转换

__setitem__按照索引赋值

__getitem__按照索引获取值

__len__获得长度

__cmp__比较运算

__call__函数调用

__add__加运算

__sub__减运算

__mul__乘运算

__div__除运算

__mod__求余运算

__pow__称方

__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法,与c++中构造函数类似。只需在自定义的类中重写__init__()方法即可。

class Person:
  def __init__(self, name, age, gender):
    print('进入Person的初始化')
    self.name = name
    self.age = age
    self.gender = gender
    print('离开Person的初始化')
  def getName(self):
    print(self.name)
# Person实例对象
p = Person('ice', 18, '男')
print(p.name)
print(p.age)
print(p.gender)
p.getName()
# 进入Person的初始化
# 离开Person的初始化
# ice
# 18
# 男
# ice

析构函数 __del__ ,__del__在对象消逝的时候被调用,当对象不再被使用时,__del__方法运行:

类的封装

python通过变量名命名来区分属性和方法的访问权限,默认权限相当于c++和java中的public

类的私有属性: __private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。

类的私有方法:__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods

虽然python不允许实例化的类访问私有数据,但可以使用 object._className__attrName 访问属性。其实python内部私有化的实现只是将attrName属性变为了_className__attrName而已

class Demo:
  __id = 123456
  def getId(self):
    return self.__id
temp = Demo()
# print(temp.__id) # 报错 AttributeError: 'Demo' object has no attribute '__id'
print(temp.getId()) # 123456
print(temp._Demo__id) # 123456

类的继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写作括号里,基本类是在类定义的时候,在元组之中指明的。

在python中继承中的一些特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。使用super().__init__()或parentClassName.__init__()

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

语法:

派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后。

多态

如果父类方法的功能不能满足需求,可以在子类重写父类的方法。实例对象调用方法时会调用其对应子类的重写后的方法

python3.3 类与继承 小例

class Base:
def __init__(self):
self.data=[]
def add(self,x):
self.data.append(x)
def addtwice(self,x):
self.add(x)
self.add(x)

# child extends base
class Child(Base):
def plus(self,a,b):
return a+b

oChild=Child()
oChild.add("str1")
oChild.add(999)
oChild.addtwice(4)
print(oChild.data)
print(oChild.plus(2,3))

以上这篇基于python3 类的属性、方法、封装、继承实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python3.3实现乘法表示例
Feb 07 Python
玩转python爬虫之爬取糗事百科段子
Feb 17 Python
python中 chr unichr ord函数的实例详解
Aug 06 Python
Python检测网络延迟的代码
May 15 Python
pandas 读取各种格式文件的方法
Jun 22 Python
Django模板语言 Tags使用详解
Sep 09 Python
python处理RSTP视频流过程解析
Jan 11 Python
关于初始种子自动选取的区域生长实例(python+opencv)
Jan 16 Python
pytorch实现从本地加载 .pth 格式模型
Feb 14 Python
Python3.8安装Pygame教程步骤详解
Aug 14 Python
Python之字典添加元素的几种方法
Sep 30 Python
Python中使用Lambda函数的5种用法
Apr 01 Python
浅谈python中列表、字符串、字典的常用操作
Sep 19 #Python
Python 文件操作的详解及实例
Sep 18 #Python
python Socket之客户端和服务端握手详解
Sep 18 #Python
Python基于time模块求程序运行时间的方法
Sep 18 #Python
Python使用当前时间、随机数产生一个唯一数字的方法
Sep 18 #Python
Python实现变量数值交换及判断数组是否含有某个元素的方法
Sep 18 #Python
Python实现输出程序执行进度百分比的方法
Sep 16 #Python
You might like
《星际争霸II》全新指挥官斯台特曼现已上线
2020/03/08 星际争霸
人大复印资料处理程序_查询篇
2006/10/09 PHP
PHP中函数rand和mt_rand的区别比较
2012/12/26 PHP
php设计模式小结
2013/02/15 PHP
php获取数组元素中头一个数组元素值的实现方法
2014/12/20 PHP
PHP Include文件实例讲解
2019/02/15 PHP
分享几种好用的PHP自定义加密函数(可逆/不可逆)
2020/09/15 PHP
js post方式传递提交的实现代码
2010/05/31 Javascript
jQuery bind事件使用详解
2011/05/05 Javascript
地址栏传递中文参数乱码在js里用escape转码
2013/08/28 Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
2014/06/24 Javascript
JavaScript处理解析JSON数据过程详解
2015/09/11 Javascript
JS实现自动定时切换的简洁网页选项卡效果
2015/10/13 Javascript
JavaScript的Backbone.js框架入门学习指引
2016/05/07 Javascript
URL的参数中有加号传值变为空格的问题(URL特殊字符)
2016/11/04 Javascript
Vue头像处理方案小结
2018/07/26 Javascript
浅谈angularJs函数的使用方法(大小写转换,拷贝,扩充对象)
2018/10/08 Javascript
详解Vue中watch的详细用法
2018/11/28 Javascript
Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)
2019/04/17 Javascript
vue swipe自定义组件实现轮播效果
2019/07/03 Javascript
JavaScript使用百度ECharts插件绘制饼图操作示例
2019/11/26 Javascript
js实现百度登录窗口拖拽效果
2020/03/19 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
2020/11/04 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
python实现通过pil模块对图片格式进行转换的方法
2015/03/24 Python
Python中的with...as用法介绍
2015/05/28 Python
详解python实现数据归一化处理的方式:(0,1)标准化
2019/07/17 Python
使用Python 自动生成 Word 文档的教程
2020/02/13 Python
深入浅析HTML5中的article和section的区别
2018/05/15 HTML / CSS
干部行政关系介绍信
2014/01/17 职场文书
革命电影观后感
2015/06/18 职场文书
会议营销主持词
2015/07/03 职场文书
2016年学校“3.12”植树节活动总结
2016/03/16 职场文书
2016年学校“6﹒26国际禁毒日”宣传活动总结
2016/04/05 职场文书
保安辞职申请书应该怎么写?
2019/07/15 职场文书
4种非常实用的python内置数据结构
2021/04/28 Python