Day26 Python面向对象

系列文章目录

Day01 软件测试基础总结

Day02 测试用例知识点总结(上)

Day03 测试用例知识点总结(下)

Day04 禅道-从安装到卸载

Day05 MySql的基础使用

Day06 MySql知识点总结

Day07 MySql知识点再总结与多表查询

Day08 redis的基础知识

Day08 VMware的安装、Linux系统安装和Linux基础命令

Day09 Linux常用命令总结

Day10 Linux环境部署和项目构建

Day11 shell脚本基础知识

Day12 接口和协议

Day13 Postman的使用

Day13 Windows环境下的JDK安装与Tomcat的启动

Day14 jenkins部署

Day15 jenkins的简单使用

Day16 charles的基本使用

Day17 考试

Day18 考试

Day19 Fiddler的简单使用

Day20 Python基础

Day21 python 语句基础

Day22 Python数据类型(上)

Day23 Python数据类型(下)

Day24 Python函数

Day25 Python的文件操作和异常处理

Day26 Python面向对象


目录

系列文章目录

前言

一、什么是面向对象

二、类与对象

1.定义类

2.创建对象

 3.在方法内通过self获取对象属性

4.魔法方法(Magic Method)

5.注意点

 三、继承和多态

四、封装

1.内部调用私有属性和私有方法

五、类属性与实例对象

六、类方法与静态方法

1.类方法

2.静态方法

3.实例方法

总结 


前言

        本章节不仅会全面描述Python中的类与对象,也会提及面向对象的三大特征封装,继承和多态。


一、什么是面向对象

        面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。

        面向对象是模型化的,你只需抽象出一个类,这是一个封闭的盒子,在这里你拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了,不必去一步一步的实现,至于这个功能是如何实现的,不需要我们了解,我们会用就可以了。

二、类与对象

类:具有相似内部状态和运动规律的实体的集合(或统称为抽象)或者说具有相同属性和行为事物的统称。即将现实的事物抽象出来,注意抽象这个词是重点啊,把现实生活的事物以及关系,抽象成类,通过继承,实现,组合的方式把万事万物都给容纳了。

对象:一个具体的事物或者你正要解决的问题,一切事物皆对象。

1.定义类

  • 定义类时有2种形式:新式类和经典类
  • object 是Python 里所有类的最顶级父类;
  • 类名 的命名规则按照"大驼峰命名法";
  • info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量 这个变量指向了实例对象
class Cat: #经典类
    def info(self):
        print('这是一个经典类')
class Dog(object): #新式类
    def info(self):
        print('这是一个新式类')

2.创建对象

cat即为创建的对象,对象创建后,可以通过对象调用类里面的方法与变量

class Cat(object):
    name='暹罗猫'
    def info(self):
        print('汪汪,喵~')

cat=Cat() #创建对象
print(cat.name)
cat.info() #通过对象调用类的方法

'''
暹罗猫
汪汪,喵~
'''

 3.在方法内通过self获取对象属性

对象创建并添加属性后,可以通过self获取对象属性

class Cat(object):
    def __init__(self):
        self.name = '暹罗猫'

    def info(self):
        print(f'{self.name}汪汪,喵~')

cat=Cat() #创建对象
print(cat.name)
cat.info() #通过对象调用类的方法

'''
暹罗猫
暹罗猫汪汪,喵~
'''

        关于self,Python 只是规定,无论是构造方法还是实例方法,最少要包含一个参数,并没有规定该参数的具体名称。之所以将其命名为 self,只是程序员之间约定俗成的一种习惯,遵守这个约定,可以使我们编写的代码具有更好的可读性。

        关于self这个参数的作用,同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象,即self这个参数只是一个钥匙,用于保证每个房子(房子代表对象)的主人仅能进入自己的房子。如此,Python解释器就能知道到底要操作哪个对象的方法了。

class Demo:
    def __init__(self):
        print(id(self))

d1=Demo()
print(id(d1))
print('= ='*5)
d2=Demo()
print(id(d2))
print('= ='*5)
d3=Demo()
print(id(d3))

'''
2225235524624
2225235524624
= == == == == =
2225235523376
2225235523376
= == == == == =
2225235521840
2225235521840
'''

4.魔法方法(Magic Method)

Python的类里提供的,两个下划线开始,两个下划线结束的方法,就是魔法方法

__init__  在类里面做属性初始化或赋值操作

class Cat(object):
    def __init__(self,name):
        self.name = name
        print('__init__先被调用')

    def info(self):
        print(f'{self.name}汪汪,喵~')

class Dog(object):
    def info(self):
        print('汪汪')

cat=Cat('暹罗猫') #创建对象,并赋值
print(cat.name)
cat.info() #通过对象调用类的方法
dog=Dog()
dog.info()

'''
__init__先被调用
暹罗猫
暹罗猫汪汪,喵~
汪汪
'''

需要注意的是所有类都继承了object类,而__init__()方法是类object中的方法,所以所有类都继承了__init__(),即即使你的类不写__init__(),系统也默认你拥有__init__()。

同时,__init__()方法,在创建对象时默认被调用,不需要手动调用

 __str__ 输出结果是该方法的返回值

class Dog(object):
    def info(self):
        print('汪汪')
    def __str__(self):
        return '狗爱吃肉'
dog=Dog()
print(dog)

'''
狗爱吃肉
'''

__call__ 对象后面加括号,会触发执行__call__方法

class Dog(object):
    def info(self):
        print('汪汪')

    def __call__(self, *args, **kwargs):
        print('嫉妒使狗面目全非')
    def __str__(self):
        return '狗爱吃肉'
dog1=Dog()
dog1()
dog2=Dog()()

'''
嫉妒使狗面目全非
嫉妒使狗面目全非
'''

__dict__ 查看类或对象中的所有成员

class Dog(object):
    def info(self):
        print('汪汪')
    def __call__(self, *args, **kwargs):
        print('嫉妒使狗面目全非')
    def __str__(self):
        return '狗爱吃肉'
print(Dog.__dict__)

'''
{'__module__': '__main__', 'info': <function Dog.info at 0x000002730E264E50>, '__call__': <function Dog.__call__ at 0x000002730E28AE50>, '__str__': <function Dog.__str__ at 0x000002730E28A820>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}
'''

__doc__  每个对象都会有一个__doc__属性,用于描述该对象的作用,相当于注解

class Dog(object):
    '''叫声'''
    def info(self):
        print('汪汪')

    def __call__(self, *args, **kwargs):
        print('嫉妒使狗面目全非')

    def __str__(self):
        return '狗爱吃肉'
print(Dog.__doc__)

'''
叫声
'''

__new__ 生成一个对象,new__优先于__init,如果定义__new__方法有返回值才会调用__init__,反之则不会调用。

class Demo:
    def __init__(self):
        print('init')

    def __new__(cls, *args, **kwargs):
        print('new')
        pass

class Demo2:
    def __init__(self):
        print('init')

    def __new__(cls, *args, **kwargs):
        print('new')
        return object.__new__(cls)

d=Demo()
print('== =='*10)
d2=Demo2()

'''
new
== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==
new
init
'''

 总结:

  1.  __new__至少要有一个参数cls代表要实例化的类,此参数在实例化时由Python解释器自动提供
  2.  __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
  3.  __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
  4.  我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节

补充:单例模式

        永远用一个对象的实例,避免新建太多实例浪费资源 

实质:使用__new__方法新建类对象时先判断是否已经建立过,如果建过就使用已有的对象

class Foo(object):
   instance = None
   def __init__(self):
      self.name = 'alex'
   def __new__(cls):
      if Foo.instance:
         return Foo.instance
      else:
         Foo.instance = object.__new__(cls)
         return Foo.instance
obj1 = Foo()
obj2 = Foo()
print(obj1,obj2)

'''
<__main__.Foo object at 0x000001E75E988DF0> <__main__.Foo object at 0x000001E75E988DF0>
'''

__del__ 析构方法,删除无用的内存对象(当程序结束会自动自行析构方法)

class Dog(object):
    def __init__(self,name):
        self.name =name
        print("__init__方法被调用")
    def __del__(self):
        print("__del__方法被调用")
        print("python解释器开始回收%s对象了" % self.name)
p = Dog('Bob')
del p

'''
__init__方法被调用
__del__方法被调用
python解释器开始回收Bob对象了
'''

1.当有变量,保存了一个对象的引用时,此对象的引用计数就会加1

2.当使用del()删除变量指向的对象时,则会减少对象的引用计数。如果对象的引用计数不为1,那么会让这个对象的引用计数减1,当对象的引用计数为0的时候,则对象才会被真正删除(内存被回收)

class Demo:
    def __del__(self):
        print('del被调用了')

d1=Demo()
d2=d1
d3=d2

del(d1)
print('= ='*5)
del(d2)
print('= ='*5)
del(d3)

'''
= == == == == =
= == == == == =
del被调用了
'''

__all__方法,可用于模块导入时限制

5.注意点

1.在类内部获取 属性 和 实例方法 ,通过self。

2.在类外部获取 属性 和 实例方法 ,通过对象名获取。

3.如果一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址

4.但是实例方法是所有对象共享的,只占一份内存空间。类会通过self判断是哪个对象调用了实例方法

 
三、继承和多态

在程序中,继承描述的是多个类之间的所属关系。

如果一个类A里面的属性和方法可以复用,则可以通过继承的方式,传递到类B中。

那么类A就是基类,也叫父类;类B就是派生类,也叫做子类。

继承分为多继承和单继承,多继承注意不能重复继承,即继承父类后,不能同时继承父类的父类

多态就是基类的同一个方法在不同派生类中有不同的功能

需要满足以下条件:

  1. 继承:多态一定是发生在子类和父类之间;
  2. 重写:子类重写了父类的方法。

例子为Dog与Cat类中的eat方法

class Animal(object):
    def __init__(self,name,address):
        self.name=name
        self.address=address

    def eat(self):
        print('动物需要吃东西')

    def sleep(self):
        print('动物需要睡觉')

    def sport(self):
        print('动物的运动')

    def __str__(self):
        return f'{self.address}的{self.name}'

class Dog(Animal):
    def eat(self):
        print('狗爱吃肉')


class Cat(Animal):
    def eat(self):
        print('猫爱吃鱼')

class XianLuo(Cat,Dog):
    def _change(self):
        print('天气变冷毛色变黑')
        Animal.sleep(self)
        super().sleep()
        cat=Cat('猫猫','本土')
        cat.sleep()

    def a(self):
        self._change()


if __name__ == '__main__':
    xiaohei=XianLuo('小黑','本地')
    xiaohei.eat()
    xiaohei.a()

'''
猫爱吃鱼
天气变冷毛色变黑
动物需要睡觉
动物需要睡觉
动物需要睡觉
'''

 在类中调用方法与属性有三种方式:(在上述代码的xianluo类中)

1.使用类名调用

2.使用super调用(super()是一个方法,常用于单继承)

3.创建一个实例对象,使用实例对象调用

四、封装

封装的意义:

1.将属性和方法放到一起做为一个整体,然后通过实例化对象来处理

2.隐藏内部实现细节,只需要和对象及其属性和方法交互就可以

3.对类的属性和方法增加,访问权限控制

私有权限:在属性名和方法名 前面加上两个下划线__

1.类的私有属性和私有方法,都不能通过对象直接访问,但是可以在本类内部访问

2.类的私有属性和私有方法,都不会被子类继承,子类也无法访问

3.私有属性和私有方法往往用来处理类的内部事情,不通过对象处理,起到安全作用

1.内部调用私有属性和私有方法

子类通过调用通过实例化方法调用私有属性和方法,不能直接调用。

通常会定义get和set方法来获取和修改私有属性

class People(object):
    def __init__(self):
        self.__money = 1000
    def set_money(self,money):
        self.__money = money
    def get_money(self):
        return self.__money
p = People()
p.set_money(2000)
print(p.get_money())

'''
2000
'''
1). 私有属性,可以在类内部通过self调用,但不能通过对象访问 
2). 私有方法,可以在类内部通过self调用,但不能通过对象访问 
3). 对象不能访问私有权限的属性和方法 
4). 子类不能继承父类私有权限的属性和方法 
5). Python中没有像C++中 public 和 private, protected 这些关键字来区别公有属性和私有属性。 
6). Python是以属性命名方式来区分,如果在属性和方法名前面加了2个下划线'__',则表明该属性和方法是私有权限,否则为公有权限。

五、类属性与实例对象

类属性就是类里面的属性与__init__()方法中使用self定义的实例属性不同,类属性可以通过类名调用,而实例属性只能通过对象调用

class People(object):
    address = '山东'  # 类属性
    def __init__(self):
        self.name = 'xiaowang'  # 实例属性
        self.age = 20  # 实例属性
p = People()
p.age = 12  # 实例属性
print(p.address)  # 正确
print(p.name)  # 正确
print(p.age)  # 正确
print(People.address)  # 正确
print(People.name)  # 错误
print(People.age)  # 错误

'''
山东
xiaowang
12
山东
'''

关于修改类属性,对象修改类属性,只对本对象有效,对别的对象没影响

class People(object):
    country = 'china' #类属性
print(People.country)
p = People()
print(p.country)
p.country = 'japan'
print(p.country)  # 实例属性会屏蔽掉同名的类属性
print(People.country)
del p.country  # 删除实例属性
print(p.country)

'''
china
china
japan
china
china
'''

六、类方法与静态方法

1.类方法

        类方法是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问

class People(object):
    # 类属性
    age= 18
    #类方法,用classmethod来进行修饰
    @classmethod
    def get_age(cls):
        return cls.age
    @classmethod
    def set_age(cls,age):
        cls.age = age
p = People()
print(p.get_age())   #可以用过实例对象访问
print(People.get_age())    #可以通过类访问
p.set_age(23)
print(p.get_age())
print(People.get_age())
p1 = People()
print(p1.get_age())

'''
18
18
23
23
23
'''

上方代码可以看出,可以使用类方法修改类属性,可以与上上次国家的修改进行比照

2.静态方法

静态方法需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数,可以通过对象和类来访问。

class People(object):
    country = 'china'
    @staticmethod
    #静态方法
    def get_country():
        return People.country
p = People()
# 通过对象访问静态方法
print(p.get_country())
# 通过类访问静态方法
print(People.get_country())

'''
china
china
'''

静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类实例对象来引用,调用静态方法可以通过对象或者类调用 

3.实例方法

实例方法中的第一个参数是self,只能通过对象来访问。

实例方法中需要self参数,因此调用实例方法只能通过实例对象调用,也可以通过类调用但是一般不这样用。

class People(object):
    def selfmethod(self):
        print("我是实例方法")
p = People()
p.selfmethod()
People.selfmethod(People())#一般不这么使用
#People.selfmethod()    #报错

'''
我是实例方法
我是实例方法
'''

总结:

  1. 类方法使用@classmethod装饰,第一个参数为类(cls),调用时可以通过类的实例或者类本身来调用。
  2. 实例方法定义时第一个参数为类的一个实例(self),调用时必须通过实例调用。
  3. 静态方法使用@staticmethod装饰,调用时可以使用类的实例或者类本身来调用。

总结 

        Python的面向对象已经基本学完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值