热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python类class学习总结(程序验证,超详细,包括多继承、循环、super().xxx等)

python类class学习总结(程序验证,超详细,包括多继承、循环、super().xxx等) ps&#xff1a

python类class学习总结(程序验证,超详细,包括多继承、循环、super().xxx等) ps:作者是很用心写的,如果觉得不错,请给作者一点鼓励噢!(点赞收藏评论噢)

  • 1 类
  • 2 类变量和实例变量
  • 3 继承
    • 3.1多继承
  • 4 循环



ps:作者是很用心写的,如果觉得不错,请给作者一点鼓励噢!(点赞收藏评论噢)
1 类

类的定义:用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
通俗来说,假设我们定义一个person类,这个类可以包括姓名、学号、爱好等这些称之为属性,这个类还可以包括比如通过学号判断打印入学年份,这个称之为方法。

类的语法格式如下

class ClassName:语句1...语句n

(1)一个对象的特征称为"属性"
(2)一个对象的行为称为"方法"
(3)属性在代码层面上来看就是变量,方法实际就是函数,通过调用这些函数来完成某些工作
(4)语句n可能是内部变量(数据、属性)的定义和赋值语句,也可能是内部方法(函数)的定义语句

示例:
随便写了一段程序,尝试了各种用法

class Person(object):#class 是关键字(表示要开始创建类了),Cc是新建的类名称,object为类的继承,没有合适的继承类用object类,这是所有类最终会继承的类country='China'#类变量,所有实例共有def __init__(self, name, age):#__init__ 用于初始化对象。第一个参数是self,实例化时不用实际传参,self在__init__里面代表实例的本身,后面的参数正常传递#它是一个实例被创建时最先被调用的函数,并且每次创建实例,它的__init__都会被调用,而且它的第一个参数永远是 self,指向创建的实例本身。self.name = name#实例变量,每个实例特有self.age=ageself.province='Shaanxi'def greet(self):print("Hi, my name is %s. I come from %s,%s. And I am %d" %(self.name,self.province,self.country,self.age))def hobby(self,hobby):self.hobby=hobbyprint("I feel like %s"%self.hobby)def repeat(self):print("Hi, my name is %s. I come from %s,%s. I am %d. And I feel like %s"%(self.name,self.province,self.country,self.age,self.hobby))#调用self.hobby可以在其他方法中使用,但是如果是hobby就只在该方法作用域内起作用
if __name__=='__main__':a=Person('Lisa',20)#类的实例化a.greet()#类的引用a.hobby('runing')a.repeat()

输出:
Hi, my name is Lisa. I come from Shaanxi,China. And I am 20
I feel like runing
Hi, my name is Lisa. I come from Shaanxi,China. I am 20. And I feel like runing

self.name = name表示:将外部传来的变量name的值赋值给当前实例对象的name属性(两个name之间无任何关系,只是变量名一致)⑴name:只是一个形参,用来接收外部传入的实参值⑵self.name:表示当前实例对象的实例属性(当前是哪个实例对象,就表示哪个实例对象的实例属性)

2 类变量和实例变量

例如上述例子country是类变量,所有实例共有。name是实例变量,个体特有。在调用一个类中的属性时,Python会先在当前实例中找,然后再到类中找。
示例:


class C:count = 0
a = C()
b = C()
c = C()
print(a.count,b.count,c.count) #output:0,0,0a.count += 10 #实例对象调用类属性
print(a.count,b.count,c.count) #output:10,0,0C.count += 100 #类对象调用类属性
print(a.count,b.count,c.count) #output:10 100 100

对实例对象的count属性进行赋值后,就相当于覆盖了类对象C的count属性,如果没有赋值覆盖,那么引用的就是类对象的count属性
⑴通过"实例对象名.属性名"来覆盖类属性,只会影响到当前实例对象,不会影响到其他实例对象中的类属性
⑵通过"类名.属性名"来覆盖类属性,会影响到所有实例的类属性
⑶因此在类外调用类变量时,最好使用"实例对象名.属性名",避免在重新赋值时影响到其他实例

类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象

该部分参照博客:https://blog.csdn.net/qq_39314932/article/details/80716295

3 继承

当我们已经创建了一个类,而又想再创建一个与之相似的类,比如添加几个方法,或者修改原来的方法,这时我们不必从头开始,可以从原来的类派生出一个新的类,我们把原来的类称为父类(基类 BaseClassName),而派生出的类称为子类(派生类 DerivedClassName),子类继承了父类的所有数据和方法(初始化和其他函数)。

示例:
我们前面已经定义了一个Person类,现在定义一个Person的子类Student

class Person(object):#class 是关键字(表示要开始创建类了),Cc是新建的类名称,object为类的继承,没有合适的继承类用object类,这是所有类最终会继承的类country='China'def __init__(self, name, age):#__init__ 用于初始化对象。第一个参数是self,实例化时不用实际传参,self在__init__里面代表实例的本身,后面的参数正常传递#它是一个实例被创建时最先被调用的函数,并且每次创建实例,它的__init__都会被调用,而且它的第一个参数永远是 self,指向创建的实例本身。self.name = nameself.age=ageself.province='Shaanxi'def greet(self):print("Hi, my name is %s. I come from %s,%s. And I am %d" %(self.name,self.province,self.country,self.age))def hobby(self,hobby):self.hobby=hobbyprint("I feel like %s"%self.hobby)def repeat(self):print("Hi, my name is %s. I come from %s,%s. I am %d. And I feel like %s"%(self.name,self.province,self.country,self.age,self.hobby))class Student(Person):def id(self,school,number):self.number=numberself.school=schoolprint("My name is %s. I am a student of %s. And my student id is %s"%(self.name,self.school,self.number))if __name__=='__main__':a=Person('Lisa',20)a.greet()a.hobby('runing')a.repeat()b=Student('Tom',18)b.id('Xidian University',18392389)b.greet()#子类继承了父类的所有方法,函数print(b.country)#子类继承了父类的所有方法,包括一开始的赋值print(b.name)#子类继承了父类的所有方法,初始化方法

输出:
Hi, my name is Lisa. I come from Shaanxi,China. And I am 20
I feel like runing
Hi, my name is Lisa. I come from Shaanxi,China. I am 20. And I feel like runing
My name is Tom. I am a student of Xidian University. And my student id is 18392389
Hi, my name is Tom. I come from Shaanxi,China. And I am 18
China

但是,如果我们在子类里面重新定义了初始化 def init()函数()(如果初始化的逻辑与父类的不同),那么子类就不再会继承父类 def init()里面的内容,也就是说python在查找方法时,会先子类里面查找,如果子类有这个函数就用子类的,如果子类没有,再去查找父类里面的这个函数。
例如下面这个例子:

class Root(object):def __init__(self):self.x= '这是属性'def fun(self):#print(self.x)print('这是方法')
class A(Root):def __init__(self):#super().__init__()#super().fun()print('实例化时执行')
test = A() #实例化类
test.fun() #调用方法
print(test.x)

输出:
实例化时执行
这是方法
Traceback (most recent call last):File "F:/shiyan.py", line 14, in print(test.x)
AttributeError: 'A' object has no attribute 'x'

**分析:**出现报错,为什么A里面没有x这个属性呢?因为我们在写程序的时候子类里面重新初始化代替父类里面的初始化了,而我们重新定义的初始化函数里面没有x属性,所以程序报错。
那么如果在子类里面重新初始化了,但是我们还想用到父类里面的初始化内容,怎么办呢?
在子类初始化函数里面加上super(Class, self).init()
ps:Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx
示例:

class Root(object):def __init__(self):self.x= '这是属性'def fun(self):#print(self.x)print('这是方法')
class A(Root):def __init__(self):super().__init__()#相比上一个程序,新添加的一行代码#super().fun()print('实例化时执行')
test = A() #实例化类
test.fun() #调用方法
print(test.x)

输出:
实例化时执行
这是方法
这是属性

完美解决报错!
注意,super().xxx里面xxx,对于上一段代码可以是_init_(),可以是fun(),但是不能是_init_里面的内容x
示例:

class Root(object):def __init__(self):self.x= '这是属性'def fun(self):#print(self.x)print('这是方法')def hello(self):print("hello")
class A(Root):def __init__(self):super().__init__()super().fun()print('实例化时执行')#print(self.x)
test = A() #实例化类
test.fun() #调用方法
print(test.x)

输出:
这是方法
实例化时执行
这是方法
这是属性

3.1多继承

看下面这个例子:

class A:def __init__(self):self.n = 2def add(self, m):print('self is {0} @A.add'.format(self))self.n += mclass B(A):def __init__(self):self.n = 3def add(self, m):print('self is {0} @B.add'.format(self))super().add(m)self.n += 3

输出:
self is <__main__.D object at 0x00000271287D3FA0> &#64;D.add
self is <__main__.D object at 0x00000271287D3FA0> &#64;B.add
self is <__main__.D object at 0x00000271287D3FA0> &#64;C.add
self is <__main__.D object at 0x00000271287D3FA0> &#64;E.add
self is <__main__.D object at 0x00000271287D3FA0> &#64;A.add
21

分析&#xff1a;
在这里插入图片描述

4 循环

如果于for…in循环&#xff0c;这时我们需要在类中定义__iter__和__next__方法。其中&#xff0c;__iter()__方法返回迭代器对象本身__next()__方法返回容器的下一个元素
示例&#xff1a;斐波那契数列

class Fib():def __init__(self):self.a, self.b &#61; 0, 1def __iter__(self):return selfdef __next__(self):self.a, self.b &#61; self.b, self.a &#43; self.breturn self.afib &#61; Fib()
for i in fib:if i > 3: breakprint(i)

输出&#xff1a;
1
1
2
3

有任何错误欢迎评论指正。作者花费了很多精力去总结&#xff0c;希望能够帮助到大家。如果您觉得写的不错的话&#xff0c;请点个赞或者收藏噢&#xff01;


推荐阅读
  • 使用Objective-C实现苹果官方NSLayoutConstraint页面布局
    本文详细介绍了如何在iOS开发中使用Objective-C语言通过NSLayoutConstraint来实现页面布局。示例代码展示了如何创建和应用约束,以确保界面元素能够正确地响应不同屏幕尺寸的变化。 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • 设计模式系列-原型模式
    一、上篇回顾上篇创建者模式中,我们主要讲述了创建者的几类实现方案,和创建者模式的应用的场景和特点,创建者模式适合创建复杂的对象,并且这些对象的每个组成部分的详细创建步骤可以是动态的变化的,但 ... [详细]
  • MVC框架下使用DataGrid实现时间筛选与枚举填充
    本文介绍如何在ASP.NET MVC项目中利用DataGrid组件增强搜索功能,具体包括使用jQuery UI的DatePicker插件添加时间筛选条件,并通过枚举数据填充下拉列表。 ... [详细]
  • 字符、字符串和文本的处理之Char类型
    .NetFramework中处理字符和字符串的主要有以下这么几个类:(1)、System.Char类一基础字符串处理类(2)、System.String类一处理不可变的字符串(一经 ... [详细]
  • 美国网络安全:MITRE Shield 积极防御知识库解析
    本文深入解析了MITRE Shield积极防御知识库,探讨其在网络安全领域的应用及意义。 ... [详细]
  • 本文探讨了在Qt框架下实现TCP多线程服务器端的方法,解决了一个常见的问题:服务器端仅能与最后一个连接的客户端通信。通过继承QThread类并利用socketDescriptor标识符,实现了多个客户端与服务器端的同时通信。 ... [详细]
  • 本文探讨了在使用 STL 容器(如 map、vector 和 list)插入自定义类对象或指针时,构造函数和析构函数的调用情况,以及可能引发的问题。 ... [详细]
  • 抽象工厂模式 c++
    抽象工厂模式包含如下角色:AbstractFactory:抽象工厂ConcreteFactory:具体工厂AbstractProduct:抽象产品Product:具体产品https ... [详细]
  • 酷家乐 Serverless FaaS 产品实践探索
    本文探讨了酷家乐在 Serverless FaaS 领域的实践与经验,重点介绍了 FaaS 平台的构建、业务收益及未来发展方向。 ... [详细]
  • 本文探讨了Web API 2中特性的路由机制,特别是如何利用它来构建RESTful风格的URI。文章不仅介绍了基本的特性路由使用方法,还详细说明了如何通过特性路由进行API版本控制、HTTP方法的指定、路由前缀的应用以及路由约束的设置。 ... [详细]
  • 在一个婚礼上,有三对情侣即将步入婚姻的殿堂,分别由A、B、C三位男士与X、Y、Z三位女士组成。为了增添婚礼的乐趣,他们决定互相开玩笑,给出了误导性的信息。A声称他将与X结婚,X则表示她的未婚夫是C,而C说自己会与Z共结连理。然而,事后发现这些话都是假的。现在的问题是,真正的配对关系究竟是怎样的? ... [详细]
  • 多用户密码验证与加密登录系统
    本文介绍了一种基于多用户密码文件的加密登录方法,通过读取用户密码文件并使用简单的加密算法实现安全登录。文中详细描述了程序的设计思路及其实现过程。 ... [详细]
  • 本文介绍如何使用Python编程语言合并字典中具有相同集合值的键,并提供两种实现方法。 ... [详细]
  • [编程题] LeetCode上的Dynamic Programming(动态规划)类型的题目
    继上次把backTracking的题目做了一下之后:backTracking,我把LeetCode的动态规划的题目又做了一下,还有几道比较难的Medium的题和Hard的题没做出来,后面会继续 ... [详细]
author-avatar
李新绿寧惠_330
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有