广告
返回顶部
首页 > 资讯 > 后端开发 > Python >day16 类
  • 449
分享到

day16 类

2023-01-30 22:01:50 449人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

初识面向对象 1.   面向过程:  一切以事物的流程为核心.  核心是"过程"二字, 过程是指解决问题的步骤, 即, 先干什么, 后⼲什么. 基于该思想编写程序就好比在编写一套流水线. 是一种机械式的编程思维 优点:  负责的问题流程化

初识面向对象

1.   面向过程:  一切以事物的流程为核心.  核心是"过程"二字, 过程是指解决问题的步骤, 即, 先干什么, 后⼲什么. 基于该思想编写程序就好比在编写一套流水线. 是一种机械式的编程思维

优点:  负责的问题流程化, 编写相对简单               

缺点:  可扩展性差

2. 面向对象: 一切以对象为中⼼.             

什么是对象?  不好解释. 先解释解释么是车?  有轱辘, 有方向盘, 有发动机, 会跑的 是车. 好. 在解释一个. 什么是人. 有名字, 年龄, 爱好, 会唱歌跳舞思考的是人. 我们给这两个 东西下了一个简单的定义.  总结: 具有相同属性和动作的结合体叫对象. 面向对象思维, 要⾃己建立对象. ⾃己建立场景. 你是就是面向对象世界中的上帝. 你想让车干嘛就干嘛. 你想让人干嘛人就能干嘛.                

优点:  可扩展性强               

缺点:  编程的复杂度高于面向过程

 

创建类:

class 类名:(类名首字母一般大写)

 

创建对象:
变量(引用, 句柄) = 类名(参数)

 

# 访问对象的属性信息
对象.属性
# 方法的访问:
对象.方法()

 

总结:

类与对象的关系:  类是对事物的总结. 抽象的概念. 类用来描述对象. 对象是类的实例化的结果. 对象能执行哪些方法. 都由类来决定. 类中定义了什么. 对象就拥有什么

 

3.⾯向对象三大特征:

封装, 继承, 多态. 只要是面向对象编程语言. 都有这三个特征.

1. 封装:  把很多数据封装到一个对象中.  把固定功能的代码封装到一个代码块, 函数, 对 象, 打包成模块. 这都属于封装的思想.

2. 继承:  子类可以自动拥有父类中除了私有属性外的其他所有内容.  说白了, 儿子可以 随便便用爹的东西. 但是朋友们, 一定要认清楚一个事情. 必须先有爹, 后有儿子.  顺序不能乱,  python中实现继承非常简单. 在声明类的时候, 在类名后面添加一个小括号, 就可以完成继承关系.两个类具有相同的功能或者特征的时候. 可以采用继承的形式. 提取⼀一个父类, 这个父类 中编写着两个类相同的部分. 然后两个类分别取继承这个类就可以了了. 这样写的好处 是我们可以避免写很多重复的功能和代码.

3. 多态: 同一个对象, 多种形态. 这个在Python中其实是很不容易说明⽩的. 因为我们⼀ 直在用. 只是没有具体的说.  比如. 我们创建一个变量a = 10 , 我们知道此时a是整数 类型. 但是我们可以通过程序让a = "ex", 这时, a又变成了字符串类型.  这是我们都知道的. 但是, 我要告诉你的是. 这个就是多态性. 同一个变量a可以是多种形态. 可能这样的程序和说法你还get不到具体什么是多态.

多态的好处:  程序具有超高的可扩展性.  面向对象思想的核心与灵魂. python自带多态

 

一.类的成员

class 类名:   

  # 方法   

  def __init__(self, 参数1, 参数2....):       

    # 属性变量       

    self.属性1 = 参数1       

    self.属性2 = 参数2        ....   

  # 方法   

  def method(self):       

    pass

  在上面代码中__init__和method都属于类的成员方法.  又称为实例⽅法.  总之这样的东⻄ 需要用对象来访问.  而上方的self.属性1 = 参数1 这个代码的含义是给对象设置属性信息. 含义是这个对象的xxx属性是xxxx. 这种东西又被称之为成员变量或者实例变量, 再或者被称之为字段. 都是一个意思.

 

二. 类的成员-变量   

在类中变量分成两⼤类: 1. 实例变量(字段) 2. 类变量(静态变量)

来做个简单的总结:   

实例变量,  给对象用的.    

类变量,  多个对象共享的. 最好是用类名来访问. 这样更加规范.

二. 类的成员-方法

1. 成员方法(实例⽅法)——对象直接访问的⽅法叫成员方法.

 

2. 静态方法

静态方法不需要我们给方法传递self.  也就是说. 当出现一个方法不需要使用到成员变量的时候. 就可以选择使用静态方法.  静态方法需要我们在方法上面添加一 个@staticmethod

 

3. 类方法

类方法和静态方法差不多, 只不过类方法需要在参数列表中的第一个位置预留一个位置, 通常我们给第一个参数起名字叫cls. 类方法在被调用的时候也不需要传递实例对象. 但是. 系统会自动的把类传递给第一个参数.  类方法在编写的时候, 需要在类方法上面添加@claSSMethod

 

面试题: 类方法/静态方法和实例方法有什么区别?

 

类的成员-属性

属性其实就是通过方法改造过来的一种变量的写法, 在方法上添加一个@property就可以 了

应用场景: 我们一般保存数据的时候, 不会保存一个人的年龄. 因为随着时间的推移. 每个人的年龄都时刻在改变着. 那如何保存加完美呢? 很简单. 保存出⽣年⽉⽇. 然后用程序来 计算,你当前的年龄. 实时的. 那这个时候就需要相应的计算了. ⽽计算属于一个功能. 当然要写方法里了. 但是对于年龄这个属性⽽言. 他应该是一个数值. ⽽不是动作. 所以python 就提供了这样一种机制. 通过方法来描述一个属性.    

注意:        

1. 方法参数只能有一个self      

 2. 方法上要写@property       

3. 调用的时候, 我们不需要写括号. 直接当成属性变量来用就可以了.        

4. 这种套路只能取值. 不能设置值

 

四. 私有   

在python中, 一般是不提倡设置和使用私有信息的. 但有些场景, 我们不得不这么做

在python中使用__作为⽅法或者变量的前缀. 那么这个方法或者变量就是一个私有的.(后缀没有_)

私有的内容不能直接访问. 但是如果对方开辟了外界访问的通道(公共方法). 那可以 通过这个公共的⽅法来获取到私有的内容.

类变量(静态变量)一样拥有这样的属性:

 

2. 私有方法   

私有方法, 顾名思义, 只能⾃己访问的方法. 别人都不能随便调用的

需要注意的是, 对于私有的内容⽽言. 子类是无法继承的.

 

类与类之间的关系:

1. 依赖关系

在方法中给方法传递一个对象. 此时类与类之间的关系是最轻的

2. 关联关系.组合关系, 聚合关系   

其实这三个在代码上写法是一样的. 但是, 从含义上是不一样的.

1. 关联关系. 两种事物必须是互相关联的. 但是在某些特殊情况下是可以更改和更换的.

2. 聚合关系. 属于关联关系中的一种特例. 侧重点是xxx和xxx聚合成xxx

3. 组合关系. 属于关联关系中的一种特例. 写法上差不多. 组合关系比聚合还要紧密. 比 如人的大脑, 心脏, 各个器官. 这些器官组合成一个人. 这时. 人如果挂了. 其他的东西 也跟着挂了

 

 继承关系

子类在不 影响父类的程序运行的基础上对父类进行的扩充和扩展. 这里.我们可以把父类被称为超类或者基类. 子类被称为派生类. 

self在访问方法的顺序:  永远先找⾃己的. ⾃己的找不到再找父类的.

self就是你访问方法的那个对象.  先找⾃己, 然后在找父类

 

类的特殊成员:.

__init_()就是一个特殊的成员. 说白了. 带双下划线的那一坨.  这些方 法在特殊的场景的时候会被自动的执行,如:

1. 类名() 会自动执行__init__()

2. 对象() 会自动执行__call__()

3. 对象[key] 会自动执行__getitem__()

4. 对象[key] = value 会自动执行__setitem__()

5. del 对象[key] 会自动执行 __delitem__()

6. 对象+对象 会自动执行 __add__()

7. with 对象 as 变量 会自动执行__enter__ 和__exit__

8. 打印对象的时候 自动执行 __str__

9. 干掉可哈希  __hash__ == None  对象就不可哈希了.

等等

 

创建对象的真正步骤:    

首先, 在执行类名()的时候. 系统会自动先执行__new__()来开辟内存. 此时新开辟出来的内 存区域是空的. 紧随其后, 系统自动调用__init__()来完成对象的初始化工作. 按照时间轴来算.

1. 加载类

2. 开辟内存(__new__)

3. 初始化(__init__)

4. 使用对象干xxxxxxxxx

 

 

一.   isinstance, type, issubclass       

先看issubclass() 这个内置函数可以帮我们判断xxx类是否是yyy类型的子类.

1 class Base:    
2     pass 
3 class Foo(Base):    
4     pass
5 class Bar(Foo):    
6     pass
7 print(issubclass(Bar, Foo))  # True
8 print(issubclass(Foo, Bar))  # False
9 print(issubclass(Bar, Base))  # True 

 

type(obj) 表示查看obj是由哪个类创建的.

可以帮我们判断xxx是否是xxx数据类型的 

type 获取到xxx对象的类型

 

isinstance也可以判断xxx是yyy类型的数据. 但是isinstance没有type那么精准.

isinstance可以判断该对象是否是xxx家族体系中的(只能往上判断)

 

如何判断一个方法或者一个函数(FunctionType, MethodType)

from types import FunctionType, MethodType

  print(isinstance(xx, FunctionType)))

  print(isinstance(xx, MethodType)))

 

二、区分方法和函数

1. 类方法. 不论任何情况, 都是方法.

2. 静态方法, 不论任何情况. 都是函数

3. 实例方法, 如果是实例(对象)访问. 就是方法. 如果是类名访问就是函数.

 

三、反射

两个函数. 一个是getattr(). 一个是hasattr().  其中getattr()用来获 取信息. hasattr()用来判断xxx中是否包含了了xxx功能,

那么我们可以在模块中这样来使用反射. 在面向对象中一样可以这样进行操作.

getattr(对象, 字符串):  从对象中获取到xxx功能. 此时xxx是一个字符串. get表示找, attr 表⽰属性(功能).

 补充:            

关于反射, 其实一共有4个函数:

1. hasattr(obj, str) 判断obj中是否包含str成员

2. getattr(obj,str) 从obj中获取str成员

3. setattr(obj, str, value) 把obj中的str成员设置成value. 注意. 这里的value可以是值, 也可以是函数或者方法

4. delattr(obj, str) 把obj中的str成员删除掉           

注意, 以上操作都是在内存中进行的. 并不会影响你的源代码

 

 约束

1. 约束(1. 抛出异常, 2. 写抽象类)
1. 抛出异常; NotImplementedError

 1 class Base:    
 2     def login(self):        
 3         raise Exception("你没有实现login⽅方法()")
 4 class NORMal(Base):    
 5     def login(self):       
 6          pass 
 7 class Member(Base):    
 8     def denglu(self):        
 9         pass 
10 class Admin(Base):    
11     def login(self):        
12         pass
13 # 项目经理理写的总入口 
14 def login(obj):    
15     print("准备验证码.......")    
16     obj.login()    
17     print("进⼊入主⻚页.......")
18 n = Normal() 
19 m = Member() 
20 a = Admin() 
21 login(n)
22 login(m)    # 报错. 
23 login(a)         

 

2. 抽象类
from abc import ABCMeta, abstractmethod

  class Base(metaclass = ABCMeta): 抽象类

    @abstractmethod
    def 方法(self):pass

  class Foo(Base): 子类必须重写父类中的抽象方法
    def 方法(self):
      pass

 1 from abc import ABCMeta, abstractmethod
 2 class Base(metaclass=ABCMeta):    
 3     @abstractmethod    
 4     def login(self):                  
 5         pass 
 6 class Normal(Base):    
 7     def login(self):   
 8         pass 
 9 class Member(Base):    
10     def denglu(self):   # 这个就没用了        
11         pass    
12     def login(self):    # ⼦类对父类进行实现        
13         pass 
14 class Admin(Base):    
15     def login(self):        
16         pass
17 # 项⽬目经理理写的总⼊入⼝口 
18 def login(obj):    
19     print("准备验证码.......")   
20     obj.login()    
21     print("进⼊入主⻚页.......")
22 n = Normal() 
23 m = Member()
24 a = Admin() 
25 login(n) 
26 login(m) 
27 login(a)    

 


一个类包含类抽象方法. 这个类一定是抽象类
抽象类中可以有正常的方法

抽象类中如果有抽象方法. 这个类将不能创建对象

接口: 类中都是抽象方法

 

2. 异常处理
try:

except Error as e:

except....

else:

finally:
收尾

import traceback
try:
# 尝试执行的代码
except Exception as e:
# 除了错之后要做什么

要引入一个模块traceback. 这个模块可以获取到我们每个方法的调用信息. 又被成为堆栈信息
traceback.format_exc() # 获取堆栈信息(错误信息)

 

3.md5加密

 MD5是一种不可逆的加密算法

1 import hashlib 
2 def my_md5(s):    
3     obj = hashlib.md5(b"fjlksajflkjasfsalwer123Dfskjf")    
4     obj.update(s.encode("utf-8"))  # 加密的必须是字节   
5     miwen = obj.hexdigest()    
6     return miwen 

 

4. 日志处理
logging

critical
error(最多)
wraning
info
debug.

1. 导入logging模块.

2. 简单配置⼀一下logging

3. 出现异常的时候(except). 向日志里写错误信息. 

# filename: 文件名

# format: 数据的格式化输出. 最终在日志文件中的样⼦子

#   时间-名称-级别-模块: 错误信息

# datefmt: 时间的格式

# level: 错误的级别权重, 当错误的级别权重大于等于leval的时候才会写⼊文件

logging.basicConfig(filename='x1.txt', format='%(asctime)s - %(name)s - %(levelname)s -% (module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=10)# 当前配置表示 10以上的分数会被写⼊入⽂文件

# CRITICAL = 50

# FATAL = CRITICAL

# ERROR = 40

# WARNING = 30

# WARN = WARNING

# INFO = 20

# DEBUG = 10

# NOTSET = 0

logging.critical("我是critical") # 50分. 最贵的

logging.error("我是error") # 40分
logging.warning("我是警告") # 警告 30

logging.info("我是基本信息") # 20

logging.debug("我是调试") # 10

logging.log(2, "我是⾃自定义") # 自定义. 看着给分

 

日志的分开记录

import logging 
# 创建一个操作日志的对象logger(依赖FileHandler) file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - % (levelname)s -%(module)s: %(message)s")) logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_handler) logger1.error('我是A系统')
# 再创建一个操作日志的对象logger(依赖FileHandler) file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s %(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('s2', level=logging.ERROR)
logger2.addHandler(file_handler2)
logger2.error('我是B系统')

 

1. 多继承
继承: x是一种y的时候.可以使用继承关系. 即"is a"关系
一个类同时继承多个类(python, c++)

 

2. 经典类的MRO
通过数型结构的深度优先遍历
一条道走到黑(从左往右)

 

3. 新式类的MRO(重点, 难点) C3算法
先拆分再合并 第一项的头和后面所有项的尾进行比较 如果出现了. 就拿出来 如果没出现. 下一项....

新式类通过__mro__可以直接看到MRO的结果

 

 1 class A:
 2     pass
 3 class B(A):
 4     pass
 5 class C(A):
 6     pass
 7 class D(B, C):
 8     pass
 9 class E(C, A):
10     pass
11 class F(D, E):
12     pass
13 class M(F, E):
14     pass
15 class N:
16     pass
17 class P(M,N):
18     pass
19 class G(P):
20     pass
21 class O:
22     pass
23 class X(O):
24     pass
25 class H(G, X, F):
26     pass
27 print(H.__mro__)
28 '''
29 L(H) = H + L(G) + L(X) + L(F) + GXF   HGPMXFDBECANO
30 
31 L(G) = G + L(P)  + P          # GPMFDBECAN
32 L(X) = X + L(O) + O           # XO 
33 L(F) = F + L(D) + L(E) + DE   #   FDBECA
34 
35 
36 L(P) = P + L(M) + L(N) + MN   #  PMFDBECAN
37 L(D) = D + L(B) + L(C) + BC   #    DBCA
38 L(E) = E + L(C) + L(A) + CA   #    ECA
39 
40 L(M) = M + L(F) + L(E) + FE   # ECA   ECA E    MFDBECA
41 
42 '''

 

4.super()

super() 找MRO顺序的下一个

super()可以帮我们执行MRO中下一个父类的方法. 通常super()有两个使用的地方:

1. 可以访问父类的构造⽅方法

2. 当子类⽅法想调用父类(MRO)中的方法 

 

结论: 不管super()写在哪儿. 在哪儿执行. 一定先找到MRO列表. 根据 MRO列表的顺序往下找. 否则一切都是错的!

--结束END--

本文标题: day16 类

本文链接: https://www.lsjlt.com/news/180245.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • day16 类
    初识面向对象 1.   面向过程:  一切以事物的流程为核心.  核心是"过程"二字, 过程是指解决问题的步骤, 即, 先干什么, 后⼲什么. 基于该思想编写程序就好比在编写一套流水线. 是一种机械式的编程思维 优点:  负责的问题流程化...
    99+
    2023-01-30
  • Python Day16 Django
    创建一个django project django-admin startproject 项目名在项目名目录下创建应用python manage.py startapp blog在project/settings.py中加入app INS...
    99+
    2023-01-31
    Python Django
  • day16-python之函数式编程匿名
    1.复习 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 name = 'alex' #name=‘lhf’ 4 def change_name(): 5 name...
    99+
    2023-01-31
    函数 python
  • Day16基础不牢地动山摇-Java基础
    目录1、反射机制1.1 认识反射1.2 取得父类信息1.3 反射调用构造1.4 反射调用方法1.5 反射调用成员1.6 反射与简单Java类—单级VO操作原理1.7 单极自动VO设置...
    99+
    2022-11-12
  • JAVA基础类库之String类,StringBuffer类和StringBuilder类
    目录引言String类String类构造方法 String常用方法:简单介绍的方法详细介绍的方法StringBuffer/StringBuilder常用方法StringBu...
    99+
    2022-11-12
  • Java 强制类型转换原理(父类转子类、子类转父类)
    在Java中,对象的强制转换(也称为类型转换)是将一个对象的引用转换为另一个类的引用,前提是这两个类之间存在继承或实现关系。强制转换可能会导致运行时异常,因为在转换的过程中,如果对象的实际类型与转换的目标类型不兼容,就会抛出ClassCas...
    99+
    2023-09-22
    java 开发语言
  • [python]父类、子类、子类实例属性
      本文旨在说明 父类、子类、子类实例的属性继承关系:     >>> A = type('A', (), {'name':1}) >>> B = type('B',(A,), {'addr':'be...
    99+
    2023-01-30
    子类 实例 属性
  • 类与数据类型
    目录 类与数据类型 list.append()方法原理 端午节刚吃完粽子写下的这篇血泪文章!!! python3中统一了类与类型...
    99+
    2023-01-31
    数据类型
  • 【JAVA】Object类与抽象类
    作者主页:paper jie_的博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将ja...
    99+
    2023-09-10
    java 开发语言
  • 类属性和类方法
    一、 类的结构 1.1 术语 —— 实例 使用面相对象开发,第 1 步 是设计 类 使用 类名() 创建对象,创建对象 的动作有两步: 1) 在内存中为对象 分配空间 2) 调用初始化方法__init__为 对象初始化 ...
    99+
    2023-01-31
    方法 类属
  • Python类之类的成员
    对于一个学C++的朋友来说,Python类中,哪些是私有成员,哪些是共有成员,估计一直傻傻分不清。 一、本篇博客要解决的问题: Python类中,哪些是私有成员?哪些是共有成员? 二、 关于Python的类 要想了解Python的类,就必...
    99+
    2023-01-31
    成员 Python
  • python标准类型分类
    一、 存储模型依据变量在内存中的组织分类。Python的类型, 就象绝大多数其它语言一样,能容纳一个或多个值。一个能保存单个字面对象的类型我们称它为原子或标量存储,那些可容纳多个对象的类型,我们称之为容器存储。(容器对象有时会在文档中被称为...
    99+
    2023-01-31
    类型 标准 python
  • Python3 类属性、类变量
      # -*- coding:utf-8 -*- # 类属性、类变量:只能由类调用的属性 class People(object): # 类变量可以由所有的对象访问,但是对象只能访问,不可修改 # 用来做资源共享...
    99+
    2023-01-31
    变量 类属
  • python3 类排序 类比较
    文章目录自定义类比较自定义类排序 自定义类比较 让python3 的类支持比较操作可以利用total_ordering修饰器重载 ==, <=, > 运算符 官方文档是这样说的 来自此文档 示例代码: 这份代码由于是...
    99+
    2023-01-31
  • day05(数字类型,字符串类型,列表类
    一,复习: 1.顺序结构、分支结构、循环结构 2.if分支结构 if 条件: 代码块 elif 条件: 代码块 else: 代码块 # 可以被if转换为False:0 | '' | None | [] | {} ...
    99+
    2023-01-31
    类型 字符串 数字
  • TypeScript联合类型,交叉类型和类型保护
    目录1.联合类型2.交叉类型3.类型保护3.1自定义类型保护3.2typeof 类型保护3.3instanceof类型保护1.联合类型 所谓的联合类型就是定义一些类型,定义的变量只...
    99+
    2022-11-12
  • Java内部类详解(含:成员内部类、局部内部类、匿名内部类、静态内部类)
    内部类是什么? 字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。 内部类是类的第五大成员→【提示:类的五大...
    99+
    2023-10-26
    jvm
  • java System类和Arrays类详解
    目录前言一.介绍二.知识点介绍三.知识点详解1、概念2、常用方法3、注意事项  4、Arrays类4.1、Arrays类的常用方法  &nbs...
    99+
    2022-11-13
  • Android View类与SurfaceView类详解
            Android游戏开发中主要的类除了控制类就是显示类,比较重要也很复杂的就是显示和游戏逻辑...
    99+
    2022-06-06
    view surfaceview Android
  • C++类常量和类枚举
    目录1.类常量2.类枚举文章转自公众号:Coder梁(ID:Coder_LT) 1.类常量 有的时候, 我们希望能给类当中定义一些常量,可以给所有类的对象使用。 比如说我们在类当中...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作