PYTHON-面向对象01

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,如果过程中有一步出现问题,那么全部过程都要重新开始。面向对象的程序设计的核心是对象,则是将对象封装成独立的,其中一块出现问题,则单独解决问题,不会影响大局。
了解一些名词:类、对象、实例、实例化
类:具有相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程
比如:多个对象–》提取对象的共同的特征和动作—》封装到一个类中。
在程序开发中,往往是先有需求,然后找出特征,在定义类。
所有的类名要求首字母大写,多个字母使用驼峰式命名。格式:

class  类名(父类):
		属性:特征
		
		方法:动作

成功定义类 —》使用类创建对象 —》查找(更改)属性

class Phone():
	#类属性,表示初始值
    brand = 'huawei'

cx = Phone()  #创建对象
#对象属性
cx.brand = 'iphone'   #从类中查到需要的属性
print(cx.brand)

属性分为类属性和对象属性,在模型里面的称为类属性,cx.brand = 'iphone’表示动态创建一个属性,在cx的空间中创建了一个brand的属性,叫做对象属性,调用的原则是先在自己的空间找brand属性,若存在,则不会去模型中找,没有,才会去模型中引用。
如何去修改类属性(初始值)?

class Phone():
    brand = 'huawei'

Phone.brand = 'oneplus'   #更改类属性,需要类去调用
cx = Phone()
print(cx.brand)

类中的方法:动作
方法种类:实例方法,类方法,静态方法,魔术方法

1.实例方法

格式:

def 方法名(self[,参数,参数]pass
class Phone():
    brand = 'huawei'
    price = 4999
    type = 'mate50'
    #类里面的方法:call
    def call(self):
        print('正在打电话....')
cx = Phone()
print(cx.brand)
cx.call()

这里的self表示谁调用call函数,谁就把自身当做参数传入call函数中,也就是自身调用自身。

class Phone():
    brand = 'huawei'
    price = 4999
    type = 'mate50'
    #类里面的方法:call
    def call(self):
        print('正在打电话....')
        print('留言:',self.note)
phone1 = Phone()
phone1.note = '我是phone1的note'
phone1.call()  #call(phone1)--->self.note
print('*'*30)
phone2 = Phone()
phone2.note = '我是phone222的note'
phone2.call()  #call(phone2)--->self.note
---------------------------------------------------
正在打电话....
留言: 我是phone1的note
******************************
正在打电话....
留言: 我是phone222的note

在phone1中添加了.note属性,然后call试图去遍历每一个对象的note属性,若phone2中没有这个属性,则会报错

class Phone():
    brand = 'huawei'
    price = 4999
    type = 'mate50'
    #类里面的方法:call
    def call(self):
        print('正在打电话....')
        print('留言:',self.note) #不能保证每个对象里面都有note
phone1 = Phone()
phone1.note = '我是phone1的note'
phone1.call()  #call(phone1)--->self.note
print('*'*30)
phone2 = Phone()

phone2.call() 
-------------------------------------------------
正在打电话....
留言: 我是phone1的note
******************************
正在打电话....
Traceback (most recent call last):

AttributeError: 'Phone' object has no attribute 'note'

2.魔术方法

__ 名字 __()

class Phone:

    def __init__(self):  #init初始的,初始化
        print('----init------')
    #类里面的方法:call
    def call(self):  #self是不断变化的
        print('价格',self.price)
p = Phone()
--------------------------------------------------
----init------

只是创建了一个对象,并没有赋值对象属性,但是有输出,表示__init__()方法是只要创建对象就会执行__init__()中的内容。此时self表示对象p

class Phone:

    def __init__(self):  #init初始的,初始化
        self.brand = 'xiaomi'
        self.price = 5000  #动态的给self空间添加了两个属性,self空间此时就是对象p的空间
    #类里面的方法:call
    def call(self):  #self是不断变化的
        print('价格',self.price)
p = Phone()

p1 = phone()

在__init__()中动态添加属性,保证每个对象空间中都有这两个属性,(模板的统一化)。init()里面的是实例对象的属性,类里面的是类的属性

class Phone:

    def __init__(self):  #init初始的,初始化
        self.brand = 'xiaomi'
        self.price = 5000  #动态的给self空间添加了两个属性,self空间此时就是对象p的空间
    #类里面的方法:call
    def call(self):  #self是不断变化的
        print('{}的价格是{}'.format(self.brand,self.price))
p = Phone()
p.brand = 'xiaomi'   #可以对自己的属性值进行更改
p.price = 3999
p.call()

p1 = Phone()
p1.brand = 'huawei'
p1.price = 4999
p1.call()
-----------------------------------------------------
xiaomi的价格是3999
huawei的价格是4999

当不需要在__init__中定义默认参数值时,则需要给__init__传参,init(self,brand,price)。传参之后,定义对象的时候需要对应的传入参数,否则就会报错

class Phone:

    def __init__(self,brand,price):
        self.brand = brand
        self.price = price

    def call(self,data):
        print('{}在{}的价格是{}'.format(self.brand,data,self.price))
p = Phone('xiaomi 10pro',5399)
p.call('2020年')

p1 = Phone('huawei mate50',5999)
p1.call('2020年')
----------------------------------------------------
xiaomi 10pro在2020年的价格是5399
huawei mate50在2020年的价格是5999

实例方法中,若在call()中定义参数,则对象在调用方法时同样需要传入相应的参数。

示例应用

class Cat:
    type = '猫'
    def __init__(self,nickname,age,color):
        self.nickname = nickname
        self.age = age
        self.color = color

    def eat(self,food):
        print('{}喜欢吃{}'.format(self.nickname,food))

    def catch_mouse(self,color,weight):
        print('{}抓了一只{}kg的{}的大老鼠!'.format(self.nickname,weight,color))

    def sleep(self,hour):
        if hour<5:
            print('乖乖继续睡觉吧!')
        else:
            print('赶紧起床抓老鼠!')

    def show(self):
        print('猫的详细信息:')
        print(self.nickname,self.color,self.age)

cat1 = Cat('花花',2,'灰色')
cat1.catch_mouse('黑色',2)
cat1.sleep(8)
cat1.eat('小金鱼')
cat1.show()

3.类方法

特点:1.定义需要依赖装饰器 @classmethod 2.类方法中参数不是一个对象,而是类 3.类方式中只可以使用类属性 4.类方法中不能使用普通方法
作用:因为只能访问类属性和类方法。所以可以在对象创建之前,如果需要完成一些动作(功能),比如需要更改类属性中的值,并不需要在创建对象的时候,更改对象的值

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

    @classmethod
    def test(cls):
        print(cls)

Dog.test()
---------------------------------------------
<class '__main__.Dog'>

可以使用类名调用方法。
类中同级方法的调用,需要通过self.方法名()进行调用

class Dog:
    def __init__(self,name):
        self.name = name
	def run(self):
		print('{}在院子里跑'.format(self.name))
	def eat(self):
		print('吃饭.....')
		self.run()   #类中同级方法的调用,
    @classmethod
    def test(cls):
        print(cls)

Dog.test()

私有化:__属性名 表示私有化,只能在类里面访问,

class Dog:
    __age = 10
    def __init__(self,name):
        self.name = name

    @classmethod
    def update_age(cls):
        cls.__age = 20    #只能在内部对__age进行操作,外部更改会报错
        print(cls.__age)
Dog.update_age()

4.静态方法

特点:1.需要一个装饰器 @staticmethod 2.静态方法是无需传递参数(cls,self) 3.也只能访问了类的属性和方法,对象是无法访问的 4.加载的时机同类方法

class Dog:
    __age = 10
    def __init__(self,name):
        self.name = name

    @classmethod
    def update_age(cls):
        cls.__age = 20
        print(cls.__age)
    @staticmethod
    def test():   #没有传入参数
        print('-------->静态方法')
        print(Dog.__age)   #用类名进行调用
Dog.update_age()
Dog.test()

类方法于静态方法的相同点:1.只能访问类的属性和方法,对象是无法访问的 2.都可以通过类名调用访问 3.都可以在创建对象之前使用,因为是不依赖于对象
实例方法与这两者的区别:1.没有装饰器 2.普通方法永远是要依赖对象,因为每个实例方法都有一个self 3.只有创建了对象才可以调用实例方法,否则无法调用。

5.魔术方法补充

  1. __ init __():初始化魔术方法
    触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
class Person:

    def __init__(self,name):
        self.name = name
        print('-------->',self.name)
        
p = Person('jack')  #初始化触发
--------------------------------------------------
--------> jack
  1. __new __:实例化的魔术方法
    触发时机:在实例化时触发
    参数:至少一个cls接收当前类
    返回值:必须返回一个对象实例
    作用:实例化对象
    注意:实例化对象是Object类底层实现,其他类继承了Object的__new__才能够实现实例化对象。
    没事别碰这个魔术方法,先触发__new__才会触发 __init __
class Person:

    # 初始化
    def __init__(self,name):
        self.name = name
        print('--------init-----------',self.name)

    # 实例化方法(构造方法)---》创建对象
    def __new__(cls, *args, **kwargs):
        print('---------new-----------')
        ret = super().__new__(cls) # 调用父类的__new__()方法创建对象,并用接收返回值
        return ret # 将对象返回给person,也就是self

p = Person('jack')
print(p)
-----------------------------------------------------
---------new-----------
--------init----------- jack
<__main__.Person object at 0x000001FF272A99E8>

  1. __ call __()
    __ call __():可以让类的实例具有类似于函数的行为,
    进一步模糊了函数和对象之间的概念。
    使用方式:对象后面加括号,触发执行。即:对象() 或者 类()()
class Person:

    def __call__(self, name):
        print('---------call------')
        print('执行得到的参数是:',name)
        
p = Person()
p('jack')
----------------------------------------------------
---------call------
执行得到的参数是: jack
  1. __ del __():析构魔术方法
    触发时机:当对象没有用(没有任何变量引用)的时候触发
    参数:至少有一个self,接收对象
    返回值:无
    作用:在对象销毁的时候做一些操作,删除某个对象对该地址的引用,查看对地址的引用次数:sys.getrefcount()
    注意:程序自动调用此方法,不需要我们手动调用。
class Person:
    def __init__(self):
        print('-----init-------')

    def __del__(self, ):
        print('删除了...')


p = Person()
p1 = p  #将对象p的地址赋给p1
del p1   #删除p1对地址空间的连接
print('---->',p)   #打印p的地址
print('---->',p1)  #由于p1与地址空间的连接已经被删除,因此p1不存在地址空间返回,会报错
-----------------------------------------------------
-----init-------
----> <__main__.Person object at 0x000001C5AE2FB6A0>
删除了...
Traceback (most recent call last):
NameError: name 'p1' is not defined
  1. __str __()
    触发时机:当打印对象名的时候,自动触发,调用里面的内容
    注意:一定要加返回值,因为打印的值是return后面的内容
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __str__(self):
        return '姓名是:'+ self.name + ',年龄是:' + str(self.age)

p = Person('tom',18)
print(p)
----------------------------------------------------
姓名是:tom,年龄是:18

单纯打印对象名称,返回的是一个地址,地址对于开发者来说没有太大意义,如果想在打印对象名的时候,给开发者更多的信息量,则需要魔术方法 __str __()

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值