python学习No7

本文深入介绍了Python中的面向对象编程,包括类的定义、对象的创建与初始化,以及面向对象的特性如属性、方法、魔法方法。详细讲解了动态属性、类属性、私有属性的使用,以及类方法和静态方法的概念。还探讨了内置属性、对象属性和类属性的区别,并展示了如何访问和修改私有属性。最后,阐述了类方法和静态方法的调用方式及其应用场景。
摘要由CSDN通过智能技术生成

面向过程和面向对象

面向过程

  • 把完成一个需求的所有步骤从头到尾逐步实现
  • 根据开发需求,将某些功夫独立的代码封装成一个又一个函数
  • 最后完成的代码,就是顺序地调用不同地函数

面向对象

  • 面向对象编程关注点在于谁来做
  • 在完成需求时,首先确定职责
  • 根据职责确定不同对象,在对象内部封装不同的方法
  • 最后完成代码,就是顺序调用不同对象的相应方法

面向对象的语法

定义类:使用class
class类名:类名一般遵守大驼峰命名法,每一个单词首字母都大写
1.class <类名>
2.class <类名>(object)

class Student(object):
    def __init__(self,name,height):
        #在__init__方法里,以参数形式定义特征,我们称之为属性
        self.name=name
        self.height=height
    def run(self):
        print('正在跑步')
    def eat(self):
        print('正在吃东西')
#Student()====>会自动调用__init__方法
#s1和s2都有name,height属性,同时都有run和eat方法
s1=Student('小明',1.75)
#Student(’小明‘,1.75)具体的操作:
#1.调用__new__申请一份内存空间
#2.调用__init__,并让self指向申请的那段内存空间
#3.让s1也指向开辟的内存空间
s2=Student('小美丽',1.65)
#根据业务逻辑,让不同的对象执行不同的行为
s1.run()
s1.eat()
s2.eat()

python的动态属性

#print(s1.city)会报错,但是创建添加并赋值就不会报错
s1.city='beijing'
print(s1.city)

改变动态属性的方法:slots

class Student(object):
    __slots__ = ('name','height')
    def __init__(self, name, height):
        # 在__init__方法里,以参数形式定义特征,我们称之为属性
        self.name = name
        self.height = height

s1=Student('小明',1.75)
print(s1.name)
s1.city='beijing'#此时这排报错
print(s1.city)

魔法方阵

魔法方法,也叫魔术方法,是在内里的特殊的一些方法
特点
1.不需要手动调用,会在合适的时机自动调用
2.这些方法,都是从_开始,使用 下划线结束
3.方法名都是系统规定好的,在合适的时机自己调用

class Person(object):
    def __init__(self,name,age):
        print("init调用了")
        self.name=name
        self.age=age
    def __del__(selfs):
        #当对象被销毁时,会自动调用这个方法
        print('__del__方法被调用了')
    def __repr__(self):
        return 'hello'
    def __call__(self,*args,**kwargs):
        print('')
p=Person('zhangsan',18)
#我们虽然没有销毁p,但是程序结束会自动销毁
#如果不做任何修改,直接打印一个对象,是文件的__name.类型 内存地址
print(p)
#当打印一个对象的时候,会调用这个对象的__str__或者__repr__方法
print(p)
#魔法方法一般自动调用,但也可以手动
print(p.__repr__())

p()#对象名()=====>调用这个对象的__call__方法
#如果类中没有call就会报错,有就不报错
#()中还可以写参数
p(1,2,3,4,m='good',n='hehehe',p='heiheihei')

其他魔法方法

class  Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
p1=Person('zhangsan',18)
p2=Person('zhangsan',18)
#p1,p2不是同一个内存空间,只是数据相同
print('0x%x'%id(p1))
print('0x%x'%id(p2))
#is 身份运算符,可以判断两个对象是否为同一个对象
print(p1 is p2)
print(p1==p2)
nums1=[1,2,3]
nums2=[1,2,3]
#is 是比较内存地址    ==是比较值
#== 是调用对象的__eq__方法,获取这个方法的比较结果
print(nums1 is nums2)#False
print(nums1==nums2)#True

有关上面p1等于p2是错误的原因,是因为==会调用对象的__eq__方法,获取这个方法的结果,eq不重写默认是比较内存地址,我们可以改写eq让他做的值比较,将类进行如下改变即可:

class  Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __eq__(self,other):
        if self.name==other.name and self.age==other.age:
            return True
        return False

self的理解:
在这里插入图片描述

和运算符相关的魔法方法:

class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __eq__(self,other):
        return self.name==other.name and self.age==other.age
    #def __ne__(self,other):
    #    pass
    def __gt__(self,other):
        return self.age>other.age
    def __ge__(self,other):#使用>=时会调用
        return self.age >= other.age

p1=Person('zhangsan',18)
p2=Person('zhangsan',18)
print(p1 is p2)#False
#==运算符本质时调用对象的__eq方法,获取__eq__方阿飞的返回结果
#a==b =====>a.__eq__(b)
print(p1==p2)#p1.__eq__(p2)
#!=本质时调用__ne__方法 或者__eq__方法取反
print(p1!=p2)
#使用>会自动调用__gt__,没写就报错,写了就会用
print(p1>p2)
print(p1>=p2)
#使用<   __lt__
#使用<=  __le__
#+    __add__
#-    __sub__
#*   __mul__
#/   __truediv_
# %  __mod__
#**  __pow__
#str()将对象转换为字符串,会自动调用__str__方法
#1.str()默认会转化成为类型+内存地址
#2.打印对象会调用
#print(p1)

将对象当作字典使用

class Person(object):
    """这是一个人类"""
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self):
        print(self.name+'正在吃饭')
p=Person('张三',18)
#'name':'zhangsan',’age‘:18,'eat':<function>
print(dir(p))#列出所有属性
print(p.__class__)#说明时什么类
print(p.__dict__)#把属性和值转换晨会一个人字典
print(p.__doc__)#打印类的说明
print(p.__module__)#__main__

class Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __setitem__(self,key,value):
        print('setitem被调用,key={},value={}'.format(key,value))
        p.__dict__[key]=value
    def __getitem__(self,item):
        return self.__dict__[item]

p=Person('张三',12)
print(p.__dict__)

#不能直接把一个对象当作字典来使用
#不能设置新值
p['name']='jack'#[]语法会调用对象的__setitem__方法
#只有重写了setitem才会不报错
print(p.name)
#不能当字典获取值,只有写了getitem才可用
print(p['name'])

内置属性

class Person(object):
    """这是一个人类"""
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self):
        print(self.name+'正在吃饭')
p=Person('张三',18)
#'name':'zhangsan',’age‘:18,'eat':<function>
print(dir(p))#列出所有属性
print(p.__class__)#说明时什么类
print(p.__dict__)#把属性和值转换晨会一个人字典
print(p.__doc__)#打印类的说明
print(p.__module__)#__main__

对象属性和类属性

类属性是所有实例对象共有的属性

class Person(object):
    type='人类'
    #type是类属性,保存在类对象中,实例对象不保存
    #定义在类里,函数之外,我们称之为类属性
    def __init__(self,name,age):
        self.name=name
        self.age=age

p1=Person('张三',18)
p2=Person('李四',19)
#p1p2是通过Person类创建出来的实例对象
#类属性是可以通过类对象和实例对象获取
print(Person.type)
print(p1.type)
#p1本身内存是没有type的,当在自身内存没有找到时,就会往类中找

#类属性只能通过类对象来修改,而实例对象不能改
p1.type='human'#并不会改变类属性,会给实例对象添加一个新的对象属性
print(Person.type)
Person.type='human'
print(p2.type)

私有属性的使用

class Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
        self.__money=100
        #__开头的是私有变量,不能通过直接获取print(p.__money)
    def get_money(self):
        return self._money
    def set_money(self,x):
        self._money=x
    def __test(self):#以两个下划线开始的函数,是私有函数,在外部无法使用
        print('我是test')
p1=Person('zhang',18)
#获取私有变量的方式:
#1.使用对象._类名_私有变量名获取
print(p1._Person__money)
#2.定义get和get获取
print(p1.get_money)
p1.set_money(100)
#3.使用property

类方法和静态方法

class Person(object):
    type='人'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self,food):#对象方法有一个参数self,指的是实例对象
        print(self.name+'正在吃'+food)
    #如果一个方法里没有用的实例对象的任何属性,可以将其设置为static
    @staticmethod
    def demo():
       print('hello')
    @classmethod
    def test(cls):#如果函数只用到了类属性,我们可以定义为一个类方法
        print('yes')   #cls==Person  ==>True
        print(cls.type)
    #cls也不用手动传参,会自动传参
    #cls指的是类对象
#在实例对象中调用方法时,不需要给形参self传参,会自动把实例对象传递给self
p=Person('张三',18)
#eat对象的、方法可以直接使用实例对象.方法名(参数)调用
#使用对象名.方法名(参数)调用的方式,不需要传递self
#会自动将对象名传递给self
#实例对象调用实例方法时,会自动将实例对象传递给self,所以会执行实例方法中的操作
p.eat('泡面')
p2=Person('李四',18)
#对象方法还可以使用类对象来调用类名.方法名()
#这种方式,不会自动给self传参,需要手动的指定self
Person.eat(p2,'西红柿')
#静态方法的调用:可以不用创建对象,直接用类调用
Person.demo()
p.demo()
#类方法:可以使用实例对象和类对象调用
Person.test()
p.test()

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值