Python:面向对象

在这里插入图片描述

1.__self__属性/动态属性的使用

# 调用__new__方法,申请一段内存空间
# 调用__init__方法,以参数的形式定义属性,并让self指向申请好的那段内存空间
# 使用Student类创建2个实例对象,让s1也指向创建好的这段内存空间
class Student(object):
    def __init__(self,x,y): # 在init方法里,以参数的形式定义属性
        self.name = x
        self.age = y

    def run(self):
        print(self.name,'在跑步')

    def eat(self):
        print(self.name,'在吃饭')

# 使用Student类创建了2个实例对象
s1 = Student('zhangsan',1)
s2 = Student('haha',18)

# 根据业务逻辑,让不同的对象执行不同的行为
s1.run()
s1.eat()
s2.run()

# 动态属性
# 直接使用等号给一个属性赋值
# 如果这个属性以前不存在,会给对象添加一个属性
# 如果这个属性以前存在,会修改这个属性和对应的值
s1.name = 'zhangliu'
s1.city = '上海'
print('name:{},city:{}' .format(s1.name,s1.city))

2. __slots__属性的使用

class Student(object):
    __slots__ = ('name') # 没写age属性,代码一运行就会报错 : AttributeError: 'Student' object has no attribute 'age'
    def __init__(self,x,y): # 在init方法里,以参数的形式定义属性
        self.name = x
        self.age = y

    def run(self):
        print(self.name,'在跑步')

    def eat(self):
        print(self.name,'在吃饭')

    def __del__(self):
        print('__del__方法被调用了')

# 使用Student类创建了2个实例对象
s1 = Student('zhangsan',1)
s2 = Student('haha',18)

# 根据业务逻辑,让不同的对象执行不同的行为
s1.run()
s1.eat()
time.sleep(10)
s2.run()

3. 魔法方法

3.1 call

import time
import datetime

class Student(object):
    
    def __init__(self,x,y): # 在init方法里,以参数的形式定义属性
        self.name = x
        self.age = y

    def run(self):
        print(self.name,'在跑步')

    def eat(self):
        print(self.name,'在吃饭')

    def __del__(self):
        print('__del__方法被调用了')

    def __call__(self,*args,**kwargs):
        print('__call__方法被调用了')
        # args是一个元祖,保存(1,2)
        # kwargs是一个字典{fn:lambda x,y:x+y}
        print('args={},kwargs={}'.format(args,kwargs)) # args=(1, 2),kwargs={'fn': <function <lambda> at 0x7ff7a0074670>}
        fn = kwargs['fn']
        return fn(args[0],args[1])

# 使用Student类创建了2个实例对象
s1 = Student('zhangsan',1)
s2 = Student('haha',18)

# 根据业务逻辑,让不同的对象执行不同的行为
s1.run()
s1.eat()
time.sleep(2)
s2.run()

n = s1(1,2,fn = lambda x,y : x+y) # 此处调用对象会报错:TypeError: 'Student' object is not callable
                                                    # 解决办法是:需要定义一个__call__方法
print(n)

⚠️在不定义__call__方法情况下调用对象,即 s1() ,会报错:‘Student" object is not callable

3.2 eq

class Person(object):
    def __init__(self,x,y):
        self.name = x
        self.age = y

    def eat(self):
        print(self.name,'在吃饭')

    def run(self):
        print(self.age,'岁的',self.name,'在跑步')

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

s1 = Person('zhangsan',15)
s2 = Person('zhangsan',15)

s1.eat()
s2.run()

print(s1 is s2) # False (比较内存地址)
print(s1 == s2) # False (比较值)🌟 s1 == s2 本质是调用s1.__eq__(s2),__eq__如果不重写,默认比较的依然是内存地址
                # True   🌟重写了__eq__方法后,代码一运行,结果为True


4.内置属性

class Person(object):
    """
    这是一段注释
    """
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def run(self):
        print(self.name,'在跑步')

    def __gt__(self,other):
        return self.age > other.age

p1 = Person('张三',15)
p2 = Person('李四',16)

p1.run()

print(dir(p1)) # 列出对象支持的所有属性和方法
print(dir(Person)) # 列出类支持的所有属性和方法
print(p1.__class__)  # <class '__main__.Person'>
print((p2.__dict__)) # {'name': '李四', 'age': 16} 把对象属性和值转换成为一个字典
print(Person.__dict__) # 把类的属性和值转换成为一个字典
print('p1.__dir__:',p1.__dir__) # 等价于print(dir(p1))
print(p1.__doc__) # 这是一段注释
print(Person.__doc__) # 这是一段注释
print(p1 > p2) # False
print(p1.__module__) # __main__

5.把对象当作字典操作

# 定义一个Person类,给个属性:name,age,city
# 创建对象p:张三,19,北京
# 将对象p转化成字典并打印出(利用内置属性__dict__)
# 将对象p像字典一样操作,修改其中的属性值:将name张三 改为 name赵四 ==>需要定义__setitem__魔法方法
# 将对象p像字典一样操作,获取字典中的值: print(p['name'])

# 定义Person类
class Person(object):
    def __init__(self,name,age,city):
        self.name = name
        self.age = age
        self.city = city

    def __setitem__(self, key, value):
        self.__dict__[key] = value  # 对应 p['name'] = '赵四'

    def __getitem__(self, item):
        return self.__dict__[item] # 对应 print(p['name']),item对应name属性

# 创建对象p
p = Person('张三',19,'北京')
print(p.__dict__) # {'name': '张三', 'age': 19, 'city': '北京'}

# 将对象p当作字典 修改其中的name属性
# 如果直接修改会报错,必须定义__setitem__属性
p['name'] = '赵四'
print(p.__dict__) # {'name': '赵四', 'age': 19, 'city': '北京'}

# 把对象p当作字典 获取其中name的值
# 如果直接修改会报错,必须定义__getitem__属性
print(p['name'])

6.对象属性和类属性

在这里插入图片描述

# 定义一个类Person,给个属性name,age
# 创建两个实例对象:p1:张三,18 ; p2:赵四,19
# 创建类属性 type = '人类'
# 获取类属性,修改类属性
class Person(object):
    # 创建类属性
    type = '人类'
    def __init__(self,name,age):
        self.name = name
        self.age = age

p1 = Person('张三',18)
p2 = Person('赵四',19)

# 获取类属性:通过类对象和实例对象获取
print(Person.type) # 人类
print(p1.type) # 人类
print(p2.type) # 人类

# 修改类属性
Person.type = 'moon'  # 修改Person类属性,将type = '人类' 改为type = 'moon'
print(Person.type) # moon
print(p1.type) # moon p1中定义了对象属性type,因此不会再去类里找类对象的类属性type
print(p2.type) # moon p2中未定义对象属性type,因此会去类里找类对象的类属性type

# 添加p1对象属性
p1.type = 'human'
print(Person.type) # moon
print(p1.type) # human
print(p2.type) # moon

7.对象方法,类方法,静态方法

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值