Python基础(类与对象)
Python基础(类与对象)
一、编程的两大思想
面向过程和面向对象
面向过程 | 面向对象 | |
---|---|---|
区别 | 事物比较简单,可以用线性的思维去解决 | 事物比较复杂,使用简单的线性思维无法解决 |
共同点:面向对象和面向过程都是解决实际问题的一种思维方式
二者相辅相成,并不是对立的,解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系,方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理
二、类
类别,分门别类,物以类聚,人类,鸟类,动物类,植物类…
- 类时多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质
三、定义Python中的类
创建类的语法
class Student: #Student为类的名称(类名),由一个或多个单词组成,每个丹迪的首字母大写,其余小写
pass
class Student: #Student为类的名称(类名),由一个或多个单词组成,每个丹迪的首字母大写,其余小写pass
class Student: #Student为类的名称(类名),由一个或多个单词组成,每个丹迪的首字母大写,其余小写passprint(id(Student))
print(type(Student))
print(Student)
输出:
1512775104816
<class 'type'> # 表明是class类型
<class '__main__.Student'>
类的组成
- 类属性
- 实例方法
- 静态方法
- 类方法
class Student:native_pace='吉林' #直接写在类里的变量,称为类属性def __init__(self,name,age):self.name=name #self.name,称为实体属性,进行了一个赋值的操作,将局部变量的name的值赋给实体属性self.age=age#实例方法def eat(self):print('学生在吃饭...')#静态方法@staticmethoddef method():print('我使用了staticmethod进行修饰,所以我是静态方法')#类方法@classmethoddef cm(cls):print('我是类方法,因为我使用了classmethod进行修饰')#在类之外定义的称为函数,在类之内定义的称为方法
def drink():print('喝水')
四、对象的创建
- 对象的创建又称为类的实例化
- 语法:
- 实例名=类名
- 例子:
- stu=Student()
- 意义:有了实例,就可以调用类中的内容
#创建Student类的对象
stu1=Student('张三',20)
print(id(stu1))
print(type(stu1))
print(stu1)
输出:
1668138946320 #转换成十六进制就是 18464D44F10
<class '__main__.Student'>
<__main__.Student object at 0x0000018464D44F10>
查看类对象
print(id(Student))
print(type(Student))
print(Student)
输出:
2460596968352
<class 'type'>
<class '__main__.Student'>
对比上面实例对象和类对象的不同
五、使用对象
调用类的方法和属性
#创建Student类的对象
stu1=Student('张三',20)
stu1.eat() #对象名.方法名()
print(stu1.name) #调用实例对象的属性
print(stu1.age)print('--------')
Student.eat(stu1) #这一行与上面调用eat()方法的功能相同,都是调用Student的eat()方法#类名.方法名(类的对象)-->实际上就是方法定义处的self
输出:
学生在吃饭...
张三
20
--------
学生在吃饭...
对比两种调用方法的方式的不同,其实功能是相同的
六、类属性_类方法__类静态方法
类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法
print(Student.native_place) #访问类属性
Student.cm() # 调用类方法
Student.sm() # 调用静态方法
类属性的使用方式
#类似属性的使用方式
print(Student.native_pace)
stu1=Student('李四',20)
stu2=Student('王五',22)
print(stu1.native_pace)
print(stu2.native_pace)
#修改类属性
print('-------------------')
Student.native_pace='天津'
print(stu1.native_pace)
print(stu2.native_pace)
吉林
吉林
吉林
-------------------
天津
天津
表明类属性是共享的
类方法的使用方式
print('-----类方法的使用------')
Student.cm()
输出:
-----类方法的使用------
我是类方法,因为我使用了classmethod进行修饰
类方法
@classmethod
def cm(cls):print('我是类方法,因为我使用了classmethod进行修饰')
类静态方法的使用
print('-----静态方法的使用------')
Student.method()
输出:
-----静态方法的使用------
我使用了staticmethod进行修饰,所以我是静态方法
静态方法
#静态方法
@staticmethod
def method():print('我使用了staticmethod进行修饰,所以我是静态方法')
七、动态绑定属性和方法
python是动态语言,在创建对象之后,可以动态地绑定属性和方法
'''
动态绑定属性和方法
'''
class Student:def __init__(self,name,age):self.name=nameself.age=agedef eat(self):print(self.name+'在吃饭')stu1=Student('lisi',20)
stu2=Student('李四',30)print(id(stu1))
print(id(stu2))
一个Student类可以创建N多个Student类的实例对象,每个实体对象的属性值不同
为某个实例对象动态绑定属性
stu1.gender='女'
print(stu1.gender)
输出:女
与java对比,属性可以在对象上动态增加
为实例对象绑定方法
类之外的方法被称为函数,将函数绑定给的对象
'''
动态绑定属性和方法
'''
class Student:def __init__(self,name,age):self.name=nameself.age=agedef eat(self):print(self.name+'在吃饭')stu1=Student('lisi',20)
stu2=Student('李四',30)print(id(stu1))
print(id(stu2))stu1.gender='女'
print(stu1.gender)#绑定方法
def show():print('定义在类之外的,称为函数')stu1.show=show
stu1.show()
输出:
2243355037648
2243355037552
女
定义在类之外的,称为函数
八、面向对象的三大特征
- 封装:提高程序的安全性
- 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行类对象的外部调用方法。这样,无需关系方法内部的具体实现细节,从而降低复杂度。
- 在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个”_“。
- 继承:提高代码的复用性
- 多态:提高程序的可扩展性和可维护性
九、封装
class Car:def __init__(self,brand):self.brand=branddef start(self):print('汽车已启动...')car=Car('宝马')
car.start()
print(car.brand)
输出:
汽车已启动...
宝马
这样就在类之外使用了封装的属性和方法
私有属性
class Student:def __init__(self,age):self.set_age(age)def set_age(self,age):if 0<=age<=120:self.__age=ageelse:self.__age=18def get_age(self):return self.__agestu1=Student(150)
stu2=Student(30)
print(stu1.get_age())
print(stu2.get_age())
私有属性
class Student:def __init__(self,name,age):self.name=nameself.__age=age #年龄不希望被外部使用,所以加了两个__def show(self):print(self.name,self.__age)
使用时:
stu1=Student('张三',21)
print(stu1.__age)
报错:
print(stu1.__age)
AttributeError: 'Student' object has no attribute '__age'
stu1=Student('张三',21)
# print(stu1.age)
stu1.show()
输出:
张三 21
在被隐藏的情况下查看私有属性
print(dir(stu1))
输出:
['_Student__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'show']
这样就可以看到有哪些属性和方法
没有找到__age属性,但是找到一个 ‘_Student__age’
print(stu1._Student__age)
输出:21
在类的外面依然可以使用,只是要麻烦一点
十、继承
语法格式
class 子类类名(父类1,父类2…) :
pass
- 如果一个类没有继承任何类,则默认继承object
- Python支持多继承
- 定义子类时,必须在其构造函数中调用父类的构造函数
定义类:
子类调用父类方法 super()
class Person(object):def __init__(self,name,age):self.name=nameself.age=agedef info(self):print(self.name,self.age)class Student(Person):def __init__(self,name,age,stu_no):super().__init__(name,age)self.stu_no=stu_noclass Teacher(Person):def __init__(self,name,age,teacherofyear):super().__init__(name,age)self.teacherofyear=teacherofyear
定义实例对象:
stu=Student('张三',20,'1001')
teacher=Teacher('李四',34,10)
调用:info()方法继承自Person类
stu.info()
teacher.info()
输出:
张三 20
李四 34
多继承
class A(object):passclass B(object):passclass C(A,B):pass
与Java不同,Java只能单继承,而Python可以搞多继承
方法重写
- 如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写
- 子类重写后的方法中可以通过super().xxx() 调用父类中被重写的方法
class Person(object):def __init__(self,name,age):self.name=nameself.age=agedef info(self):print(self.name,self.age)class Student(Person):def __init__(self,name,age,stu_no):super().__init__(name,age)self.stu_no=stu_nodef info(self):super().info()print(self.stu_no)stu=Student('张三',25,'1001')stu.info()
子类重写了父类的info()方法
输出:
张三 25
1001
十一、object类
object类是所有类的父类,因此所有类都有object类的属性和方法。
内置函数dir()可以查看指定对象的所有属性
Object有一个 " __ str __ () " 方法,用于返回一个对于“对象的描述” ,对应于内置函数str()
经常用于print()方法,帮我们查看对象的信息,所以我们经常会对 __ str __ () 进行重写
class Student:passstu=Student() print(dir(stu))
查看对象的所有属性
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
打印对象
print(stu)
输出:
<__main__.Student object at 0x000001EF126D58E0>
查看对象信息
先重写方法 __ str __ ()
class Student:def __init__(self,name,age):self.name=nameself.age=agedef __str__(self):return '我的名字是{0},今年{1}岁'.format(self.name,self.age)stu=Student('张三',26)
print(dir(stu))
print(stu)
输出:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
我的名字是张三,今年26岁
当你重写了 str 方法后,你再打印对象,就不会再打印对象的内存地址,而是调用 str 函数
str 方法经常重写,用于返回对象的描述
查看类型
print(type(stu))
<class '__main__.Student'>
会是创建时的子类类型,而不是object
十二、多态
简单地说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。
class Animal(object):def eat(self):print('动物会吃')class Dog(Animal):def eat(self):print('狗吃骨头')class Cat(Animal):def eat(self):print('猫吃鱼')class Person(object):def eat(self):print('人吃五谷杂粮')#定义一个函数
def fun(obj):obj.eat()#开始调用函数
fun(Cat())
fun(Dog())
fun(Animal())
fun(Person())
输出:
猫吃鱼
狗吃骨头
动物会吃
人吃五谷杂粮
这样,就根据传入的对象类型,进行不同的输出
没有继承,也能实现多态,跟Java有区别
静态语言和动态语言
- 静态语言和动态语言关于多态的区别
- 静态语言实现多态的三个必要条件
- 继承
- 方法重写
- 父类引用指向子类对象
- 静态语言实现多态的三个必要条件
- 动态语言的多态崇尚“鸭子类型” 当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不用关心对象时什么类型,到底是不是鸭子,只关心对象的行为。
十三、特殊方法和特殊属性
名称 | 描述 | |
---|---|---|
特殊属性 | __ dict __ | 获得类对象或实例对象所绑定的所有属性和方法的字典 |
以下为特殊方法 | __ len __ () | 通过重写 __ len __ () 方法,让内置函数len() 的参数可以是自定义类型 |
__ add __ () | 通过重写 __ add __ () 方法,可以使自定义对象具有 “+” 功能 | |
__ new __ () | 用于创建对象 | |
__ init __ () | 对创建的对象进行初始化 |
特殊属性
- __ dict __
class A:passclass B:passclass C(A,B):def __init__(self,name,age):self.name=nameself.age=agedef roar(self):print('C is roar')#创建C类的对象
x=C('Jack',20)
print(x.__dict__) #实例对象的属性字典
print(C.__dict__) #类对象的属性和方法字典
#该部分代码,后续的几个方法 里 x C 都指的这里面的
输出:
{'name': 'Jack', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x00000199020715E0>, 'roar': <function C.roar at 0x00000199022821F0>, '__doc__': None}
__ class __
print(x.__class__) #输出实例对象所属的类
输出:
<class '__main__.C'>
__ bases __
print(C.__bases__) # 输出类的父类的元祖,因为可能不止继承一个,只看上一级
输出:
(<class '__main__.A'>, <class '__main__.B'>)
__ base __
print(C.__base__) # 输出类的父类,如果有多个,就只输出第一个,只看上一级
输出:
<class '__main__.A'>
__ mro __
print(C.__mro__) # 输出类的层级关系
输出:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
__ subclasses __
print(A.__subclasses__()) # 输出类的子类class D(A):passprint(A.__subclasses__())
输出:
[<class '__main__.C'>, <class '__main__.D'>]
输出的是子类的列表
特殊方法
__ add __()方法
- 让两个对象相加
a=20 b=100 c=a+b d=a.__add__(b)print(c) print(d)
输出:
120
120
这里相加的都是整数
但是,如果是两个自定义的实例对象呢
class Student:def __init__(self,name):self.name=name# def __add__(self, other):# return self.name + other.namestu1=Student('张三')
stu2=Student('李四')s= stu1+stu2
报错:
s= stu1+stu2
TypeError: unsupported operand type(s) for +: 'Student' and 'Student'
但是把 __ add __() 方法放开:
class Student:def __init__(self,name):self.name=namedef __add__(self, other):return self.name + other.namestu1=Student('张三')
stu2=Student('李四')s= stu1+stu2
print(stu1+stu2)
print(stu1.__add__(stu2))
输出:
张三李四
张三李四
在定义过后,就可以相加了
要实现两个对象的加法运算,需要在两个对象的父类编写 __ add __() 特殊方法
__ len __() 方法
输出对象的长度
lst=[22,33,55,66]
print(len(lst))
print(lst.__len__())
输出:
4
4
len(lst) 这里使用的是内置函数,lst. __ len __() 列表对象本来就有这个方法
但是:问题是,自定义的对象没有
上面定义的 stu1 不能使用这个方法,必须自定义
class Student:def __init__(self,name):self.name=namedef __len__(self):return len(self.name)stu1=Student('张三')
stu2=Student('李四')print(stu1.__len__())
输出:
2
stu2=Student('李四2')
print(stu2.__len__())
输出:
3
十四、__ new __ 与 __ init __ 演示创建对象的过程
class Person(object):def __new__(cls, *args, **kwargs):print('__new__被执行了,cls的id值为{0}'.format(id(cls)))obj=super().__new__(cls)print('创建的对象的id为:{0}'.format(id(obj)))return objdef __init__(self, name, age):print('__init__被调用了,self的id值为:{0}'.format(id(self)))self.name=nameself.age=ageprint('object这个类对象的id为:{0}'.format(id(object)))
print('Person这个类对象的id为:{0}'.format(id(Person)))#创建Person类的实例对象
p1=Person('张三',20)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))
输出:
object这个类对象的id为:140715602066944
Person这个类对象的id为:3186528480864
__new__被执行了,cls的id值为3186528480864
创建的对象的id为:3186530217744
__init__被调用了,self的id值为:3186530217744
p1这个Person类的实例对象的id:3186530217744
Python基础(类与对象)相关推荐
- Python基础——类与对象
Python基础--类与对象 Python基础--类与对象 类与对象 数据类型 对象 类的创建 创建语法 类的创建 对象的创建 对象调用类中的内容 类属性,类方法,静态方法 类属性 访问类属性 类方法 ...
- python基础------类与对象之间的关系,封装、继承、多态
类与对象.封装.继承 练习1 # 1.写一个员工类BwEmployee class BwEmployee(object): # (2)添加构造方法,包含5个形参,保存外部传入值,分别给以下实例属性赋值 ...
- python基础类型,Python基础-类
Python基础-类 @(Python)[python, python基础] 写在前面 如非特别说明,下文均基于Python3 摘要 本文重点讲述如何创建和使用Python类,绑定方法与非绑定方法的区 ...
- Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法
Day09新手小白学python 第九节 Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法 目录 Day09新手小白学python 前言 一.面向对象介绍 二 ...
- ios开发之OC基础-类和对象
ios开发之OC基础-类和对象 本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录 ...
- Python的零基础超详细讲解(第十三天)-Python的类与对象
基础篇往期文章如下: Python的零基础超详细讲解(第一天)-Python简介以及下载 Python的零基础超详细讲解(第二天)-Python的基础语法1 Python的零基础超详细讲解(第三天)- ...
- 求python一个类与对象的代码_Python基础系列(五)类和对象,让你更懂你的python代码...
首先,非常感谢各位打开本博文,本博文是Python入门基础系列文章之一,Python目前是非常火的编程工具,其实作为编程不在只是程序员的专利,每一个人在日常的工作中.学习中都会或多或少的要用到一些工具 ...
- python编程基础—类与对象
1.类的声明与定义 Python 是一门面向对象的语言. 面向对象编程 - Object Oriented Programming(简称 OOP)是一种编程思想,在面向对象编程中,把对象作为程序的基本 ...
- python描述符魔术方法_学习笔记-Python基础9-面向对象编程OOP-类的成员描述符(property)、类的常用内置属性、类的常用魔术方法、类和对象的三种方法...
一.类的成员描述符(property) 类的成员描述符是为了在类中,对类的成员属性进行相关操作而创建的一种方式,大部分属于数据清洗 属性有三种操作:get获取属性值.set修改或添加属性.delete ...
最新文章
- 10秒完成Linux系统pip在线安装
- linux nat span端口镜像,端口镜像span、rspan实现数据检测
- cx oracle 返回码,oracle错误代码处理cx_oracle
- [Termux]给Termux安装一个发行版Linux
- 第三次学JAVA再学不好就吃翔(part76)--Collection类
- dayjs​​​​​​​文档
- IOS机型margin属性无效问题
- android sha1和签名证书的学习
- 部署到gcp_将S/4部署在“大型公有云”上
- 《Objective-C 程序设计(第4版)》图书信息(二)
- Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
- [HDU 5349] MZL's simple problem 神题
- 计算机操作系统存在的意义,电脑操作系统的作用
- 移动端web设计尺寸_移动端之Web及app设计尺寸
- realtek是什么意思_realtek bluetooth是什么意思
- 小米air2se耳机只有一边有声音怎么办_双十一高性价蓝牙耳机排名,500元内真无线蓝牙耳机推荐...
- 前端使用xlsx、file-saver实现自定义excel格式导出(列宽、字体、边框、行高)
- xxxxxlllllxl的专栏 链接,很多实际动手操作的东西
- 桂林山水甲天下,阳朔山水甲桂林
- Python函数设计与使用