Python面向对象编程

news2024/9/21 12:29:05

本篇内容:

  •   1、反射
  •   2、面向对象编程
  •   3、面向对象三大特性
  •   4、类成员
  •   5、类成员修饰符
  •   6、类的特殊成员
  •   7、单例模式

反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

import commas同等于下面字符串导入模块

inp = input("请输入模块名:")
dd = __import__(inp)

ret =dd.f1()
print(ret)

通过字符串的形式导入模块

 通过字符串的形式导入模块

#应用根据用户输入导入模块
inp = input("请输入模块:")
inp_func = input("请输入执行的函数:")

# __import__以字符串的形式导入模块
moudle = __import__(inp)
#getattr  用以去某个模块中寻找某个函数
target_func = getattr(moudle,inp_func)

relust = target_func()
print(relust)

指定函数中执行指定函数

 指定函数中执行指定函数

1、getattr
通过字符串的形式去某个模块中寻找东西
import commas

#去commas,寻找name变量,找不到返回none
target_func = getattr(commas ,"name",None)
print(target_func)
demo

 demo

2、hasattr
通过字符串的形式去某个模块中判断东西是否存在
import commas

#去commas模块中寻找f1,有返回true,没有返回none
target_func = hasattr(commas,"f1")
print(target_func)
demo

 demo

3、setattr
通过字符串的形式去某个模块中设置东西
import commas

#去commas模块中寻找name,有返回true,没有返回none
target_func1 = hasattr(commas,"name")
print(target_func1)

#在内存里往commas模块中添加name = "zhangyanlin"
setattr(commas,"name","zhangyanlin")
#在内存里往commas模块中创建函数
setattr(commas,"f3",lambda x: "zhen" if x >10 else "jia")

#去commas模块中寻找name,有返回true,没有返回none
target_func = hasattr(commas,"name")
print(target_func)

demo
import commas

#去commas模块中寻找name,有返回true,没有返回none
target_func1 = hasattr(commas,"name")
print(target_func1)

#在内存里往commas模块中添加name = "zhangyanlin"
setattr(commas,"name","zhangyanlin")
#在内存里往commas模块中创建函数
setattr(commas,"f3",lambda x: "zhen" if x >10 else "jia")

#去commas模块中寻找name,有返回true,没有返回none
target_func = hasattr(commas,"name")
print(target_func)
4、delattr
import commas

target_func = hasattr(commas,"f1")
print(target_func)

del_func = delattr(commas,"f1")

target_func = hasattr(commas,"f1")
print(target_func)

demo

 demo

  案例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

'''

基于web框架实现路由功能

'''

url = str(input("请输入URL:"))  #输入URL,先输入模块,后面加函数

target_moudle,target_func = url.split("/"# 用/把分割开,前面是模块 后面是函数

moudle = __import__(target_moudle,fromlist=True)  #导入模块

if hasattr(moudle,target_func):   #判断模块里有这个函数

    target_func = getattr(moudle,target_func)   #找到那个函数

    ret = target_func()   #执行函数

    print(ret)

else:                 #否则报错

    print("404") 

class Foo:

    def __init__(self,name):
        self.name = name

    def login(self):
        print("登录请按1:")

obj = Foo("zhangyanlin")
ret = getattr(obj,"name")
print(ret)
#反射
#以字符串的形式去对续航中操作成员
#反射:类,只能找类的成员
ret = hasattr(Foo,"login")
print(ret)

#反射:对象,既可以找对象也能找类的成员
ret = hasattr(obj,"name")
print(ret)
ret = hasattr(obj,"login")
print(ret)

反射类实例

 反射类实例

面向对象编程

  • 面向过程:根据业务逻辑从上到下写垒代码
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。

1、创建类和对象

面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

  类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

  对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

  • class是关键字,表示类
  • 创建对象,类名称后加括号即可

1

2

3

4

5

6

7

8

9

10

11

12

13

# 创建类

class Foo:

      

    def Bar(self):

        print 'Bar'

  

    def Hello(self, name):

        print 'i am %s' %name

  

# 根据类Foo创建对象obj

obj = Foo()

obj.Bar()            #执行Bar方法

obj.Hello('wupeiqi'#执行Hello方法 

一、封装

封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。所以,在使用面向对象的封装特性时,需要:

  • 将内容封装到某处
  • 从某处调用被封装的内容

第一步:将内容封装到某处

demo

class Foo:
 
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
obj1 = Foo('张岩林', 18)
print(obj1.name)    # 直接调用obj1对象的name属性
print(obj1.age)     # 直接调用obj1对象的age属性
 
obj2 = Foo('Aylin', 18)
print(obj2.name)    # 直接调用obj2对象的name属性
print(obj2.age )    # 直接调用obj2对象的age属性

第二步:从某处调用被封装的内容调用被封装的内容时,有两种情况:

  • 通过对象直接调用
  • 通过self间接调用

1、通过对象直接调用被封装的内容上图展示了对象 obj1 和 obj2 在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象.属性名

 

demo 2、通过self间接调用被封装的内容执行类中的方法时,需要通过self间接调用被封装的内容

demo 二、继承继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。例如:  猫可以:喵喵叫、吃、喝、拉、撒  狗可以:汪汪叫、吃、喝、拉、撒吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现:  动物:吃、喝、拉、撒     猫:喵喵叫(猫继承动物的功能)     狗:汪汪叫(狗继承动物的功能)

demo所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已。

 那么问题又来了,多继承呢?

  • 是否可以继承多个类
  • 如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?

1、Python的类可以继承多个类,Java和C#中则只能继承一个类 

demo 三、多态  Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

python伪代码实现java,c#多态

python“鸭子类型” 类成员  1、字段:
静态字段:提供给类里每个对象(方法)使用
普通字段:让每个方法都有不同的数据

2、方法:
静态方法: 无需使用对象封装,用类方法执行
类方法: 类方法执行,调用时会显示出当前是哪个类
普通方法: 对象方式执行,使用对象中的数据

3、特性:
可以获取特性 也可以设置特性

一、字段字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,

  • 普通字段属于对象
  • 静态字段属于

View Code由上述代码可以看出【普通字段需要通过对象来访问】【静态字段通过类访问】,在使用上可以看出普通字段和静态字段的归属是不同的。其在内容的存储方式类似如下图:

注:静态字段只在内存中保存一份,普通字段在每个对象中都要保存一份 二、方法方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。  1、普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;  2、类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls;  3、静态方法:由调用;无默认参数;

定义方法并使用

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。不同点:方法调用者不同、调用方法时自动传入的参数不同。 三、特性  如果你已经了解Python类中的方法,那么特性就非常简单了,因为Python中的属性其实是普通方法的变种。对于特性,有以下两个知识点:  1、特性的基本使用  2、特性的两种定义方式 1、特性的基本使用

特性

由属性的定义和调用要注意一下几点:  1、定义时,在普通方法的基础上添加 @property 装饰器;  2、定义时,属性仅有一个self参数  3、调用时,无需括号
           方法:foo_obj.func()
           属性:foo_obj.prop注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象        属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:  1、根据用户请求的当前页和总数据条数计算出 m 和 n  2、根据m 和 n 去数据库中请求数据 

View Code 2、属性的两种定义方式属性的定义有两种方式:  1、装饰器 即:在方法上应用装饰器  2、静态字段 即:在类中定义值为property对象的静态字段 1.1 装饰器方式经典类,具有一种@property装饰器

View Code新式类,具有三种@property装饰器

View Code注:1、经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
     2、新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

View Code 1.2 静态字段方式,创建值为property对象的静态字段当使用静态字段的方式创建属性时,经典类和新式类无区别

View Codeproperty的构造方法中有个四个参数  1、第一个参数是方法名,调用 对象.属性 时自动触发执行方法  2、第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法  3、第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法  4、第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

View Code由于静态字段方式创建属性具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

View Code所以,定义属性共有两种方式,分别是【装饰器】和【静态字段】,而【装饰器】方式针对经典类和新式类又有所不同。 类成员修饰符 类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式:  1、公有成员,在任何地方都能访问  2、私有成员,只有在类的内部才能方法 私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等) 

1

2

3

4

5

class C:

  

    def __init__(self):

        self.name = '公有字段'

        self.__foo = "私有字段"

私有成员和公有成员的访问限制不同: 1、静态字段  1、公有静态字段:类可以访问;类内部可以访问;派生类中可以访问  2、私有静态字段:仅类内部可以访问;

公有字段

私有字段2、普通字段  1、公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问  2、私有普通字段:仅类内部可以访问;注:如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。 

公有字段

私有字段 类的特殊成员 1、 __doc__  表示类的描述信息

View Code2、 __module__ 和  __class__   __module__ 表示当前操作的对象在那个模块  __class__     表示当前操作的对象的类是什么

lib/test.py

index3、 __init__  构造方法,通过类创建对象时,自动触发执行。 

View Code

继承父类__init__ 4、 __del__  析构方法,当对象在内存中被释放时,自动触发执行。注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。 

code 5、 __call__  对象后面加括号,触发执行。注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

View Code6、 __dict__  类或对象中的所有成员上文中我们知道:类的普通字段属于对象;类中的静态字段和方法等属于类,即:

View Code7、 __str__如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

View Code8、__getitem__、__setitem__、__delitem__用于索引操作,如字典。以上分别表示获取、设置、删除数据

View Code9、 __iter__ 用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__ 

View Code

for循环内部语法 单例模式 所谓单例,是指一个类的实例从始至终只能被创建一次。 方法1如果想使得某个类从始至终最多只有一个实例,使用__new__方法会很简单。Python中类是通过__new__来创建实例的:

1

2

3

4

5

6

7

8

9

10

11

12

13

class Singleton(object):

    def __new__(cls,*args,**kwargs):

        if not hasattr(cls,'_inst'):

            cls._inst=super(Singleton,cls).__new__(cls,*args,**kwargs)

        return cls._inst

if __name__=='__main__':

    class A(Singleton):

        def __init__(self,s):

            self.s=s    

    a=A('apple'

    b=A('banana')

    print(id(a),a.s)

    print(id(b),b.s)

结果:

1

2

29922256 banana

29922256 banana

通过__new__方法,将类的实例在创建的时候绑定到类属性_inst上。如果cls._inst为None,说明类还未实例化,实例化并将实例绑定到cls._inst,以后每次实例化的时候都返回第一次实例化创建的实例。注意从Singleton派生子类的时候,不要重载__new__。 方法2当你编写一个类的时候,某种机制会使用类名字,基类元组,类字典来创建一个类对象。新型类中这种机制默认为type,而且这种机制是可编程的,称为元类__metaclass__ 。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

class Singleton(type):

    def __init__(self,name,bases,class_dict):

        super(Singleton,self).__init__(name,bases,class_dict)

        self._instance=None

    def __call__(self,*args,**kwargs):

        if self._instance is None:

            self._instance=super(Singleton,self).__call__(*args,**kwargs)

        return self._instance

if __name__=='__main__':

    class A(object):

        __metaclass__=Singleton     

    a=A()

    b=A()

    print(id(a),id(b))

结果:

1

34248016 34248016

id是相同的。例子中我们构造了一个Singleton元类,并使用__call__方法使其能够模拟函数的行为。构造类A时,将其元类设为Singleton,那么创建类对象A时,行为发生如下:A=Singleton(name,bases,class_dict),A其实为Singleton类的一个实例。创建A的实例时,A()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__(),这样就将A的所有实例都指向了A的属性_instance上,这种方法与方法1其实是相同的。 方法4最简单的方法:

1

2

3

class singleton(object):

    pass

singleton=singleton()

将名字singleton绑定到实例上,singleton就是它自己类的唯一对象了。 方法5

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

class ConnectionPool:

    __instance = None

    def __init__(self):

        self.ip = "192.168.1.1"

        self.port = 3306

        self.username = "zhangyanlin"

        self.pwd = 123456

    @staticmethod

    def get_instance():

        if ConnectionPool.__instance:

            return ConnectionPool.__instance

        else:

            ConnectionPool.__instance = ConnectionPool()

            return ConnectionPool.__instance

obj1 = ConnectionPool()

print(obj1.get_instance())

obj2 = ConnectionPool()

print(obj2.get_instance())

obj3 = ConnectionPool()

print(obj3.get_instance())

定义静态方法,判断让所有只用第一个对象在内存中创建的ID         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/58146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

m基于GA遗传算法的高载能负荷响应优化控制模型matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 高载能企业执行子站接收负荷调整指令后,需将有功功率、无功功率调整总量合理分配给各用能设备/系统。研究高载能负荷响应优化控制模型,建立以高载能企业响应效益最优为目标…

ccf序列查询新解python满分_纯数学规律(学霸怎么想到的啊......)

题目 思路和代码 这题我也就看了好几个小时吧。终于!有点懂了! 上午看懂了用双指针写《下一个排序》后就在看这题。70分的代码很好写也很好想,就是模拟fx和gx,然后遍历一趟,得到最终的结果。 看了学霸的代码&#x…

使用桥梁振动自动识别车辆(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

Qt在线安装教程(详细图文)

Qt在线安装教程(详细图文一、前言二、QT账号的注册三、QT的安装的镜像四、安装的过程一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡,小伙伴们,让我们一起来学习Qt在线安装。如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二、QT账号…

js-mark新时代的网页标记容器

js-mark 🖍️️ ✨ 它提供了一组可交互操作的工具来注释网页内容 ✨🖍️ js-mark是一个JavaScript库,用于在浏览器。他是一个可以在任何网页做标记的前端库, 它提供了一组可交互操作的工具来注释网页内容。 支持标记文本和 持久化存储与还原…

LSTM和双向LSTM讲解及实践

目录: RNN的长期依赖问题LSTM原理讲解双向LSTM原理讲解keras实现LSTM和双向LSTM RNN 的长期依赖问题 在上篇文章中介绍的循环神经网络RNN在训练的过程中会有长期依赖的问题,这是由于RNN模型在训练时会遇到梯度消失(大部分情况)或者梯度爆炸(很少&…

网络1323的分类行为

( A, B )---2*30*2---( 1, 0 )( 0, 1 ) 用网络分类A和B,让A是(0,1)(1,1),让B是(1,0)(1,1)。测试集为&#xf…

[附源码]计算机毕业设计springboot学生在线考试系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

408 考研《操作系统》第一章第三节:中断和异常、系统调用

文章目录教程1.中断和异常1.1 中断的作用1.2 中断的类型1.2.1 外中断的处理过程1.2.1 内中断的处理过程1.3 中断机制的基本原理1.4 总结2. 系统调用2.1 什么是系统调用?2.2 小例子:为什么系统调用是必须的?2.3 什么功能要用系统调用实现&…

m基于随机接入代价的异构网络速率分配算法matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 无线接入技术发展迅速,异构网络并存的现象普遍存在;同时,随着终端用户数量的剧增、业务类型的多样化和高服务质量多媒体数据业务需求的增加,通过异…

磨金石教育插画技能干货分享|插画怎么配色才好看?

在绘画界,配色是非常重要的步骤,一幅作品能够展现出什么样的品质,配色起着举足轻重的作用。颜色配的好会给作品晋商添花,配的不好,就会让作品失去水准,缺少神韵。 所以想学好插画,就要在在配色上…

python离线环境下安装第三方模块的方法

一.背景 1.背景: 在实际开发中,我们自己电脑上方便上网可以随时安装自己需要的包文件,但是有的项目现场不能联网或者现场是“内网”不具备联网条件,所以必须解决在“离线电脑上”安装需要的软件包的问题。 2.环境说明以及实现步…

SpringCloud微服务项目实战 - 项目搭建

面对大河我无限惭愧 我年华虚度空有一身疲倦 系列文章目录 项目搭建app登录 一、项目介绍 1. 项目背景 项目概述: 类似于新闻头条,是一个新闻资讯类项目 (这里之后放项目APP端的截图) 技术架构: 项目术语&…

Ubuntu18.04安装ROS、Gazebo、Mavros、PX4、QGC教程

修改国内源 修改apt sudo cp /etc/apt/source.list /etc/apt/source.list.old sudo gedit /etc/apt/source.list输入如下进行保存 deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic m…

转行|什么是游戏建模??小本本记下来

今天来说一下游戏建模…小本本记下来 👀3D手绘建模 3D美术设计师根据原画设计师的构思,将二维的东西在3D软件里面制作出来,最终得到的东西是模型( 3Dmax )和贴图(软件PS、Bodypaint ) ,模型是物体的主要构架&#xff…

Kaggle Feedback Prize 3比赛总结:两种模型设计思路

比赛的目标:本次竞赛的目标是评估8-12年级英语学习者(ELLs)的语言能力。利用英语学习者所写的论文数据集开发出能更好地支持所有学生的能力模型,帮助ELL学生在语言发展方面得到更准确的反馈,并加快教师的评分周期。 方…

RestTemplate使用InputStreamResource上传文件

背景 1. 我们应用服务是Spring boot项目,预览服务是我们另一个团队提供的用.net写的,最终使用的是office online来实现文件预览的功能。 2. 我们文件在阿里云OSS存储,我们需要预览文件需要将文件上传至预览服务器。 3. 计划使用RestTemplate…

线程池自查注意点

文章目录线程池自查注意点1、线程池的标准创建方式2、线程池的任务调度流程3、避免使用Executors快捷创建线程池3.1、newSingleThreadExecutor()3.2、newCachedThreadPool()3.3、ScheduledThreadPool()4、避免在方法中创建线程池5、不要盲目使用同步队列6、使用线程池&#xff…

MySQL库的操作

文章目录MySQL库的操作创建数据库创建数据库案例字符集和校验规则查看系统默认字符集以及校验规则查看数据库支持的字符集查看数据库支持的字符集校验规则校验规则对数据库的影响操纵数据库查看数据库显示创建语句修改数据库删除数据库备份和恢复数据库的备份和恢复表的备份和恢…