python面向对象编程

  • class表明这是一个类
  • object:父类的名字,定义的类继承自父类,不写的时候默认是object。object是所有类的直接或间接父类
  • 创建对象就是类的实例化:实例名=类()
class Player(object):
    pass
rado=Player()
rado.name="rado"#这些都是给实例增加属性
rado.age=18#这些都是给实例增加属性
print(type(rado))#<class '__main__.Player'>
print(type(rado.age))#<class 'int'>
print(isinstance(rado, Player))#True
print(isinstance(rado,object))#True

规范一点的话,name、age是这个类所具有的共同特征,没必要单独增加,所以应该这样做

class Player(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
rado=Player("rado",18)
print(rado.name,rado.age)#rado 18

这里看一下新增的内容

class Player(object):
    def __init__(self):#self代表了rado这个实例化对象
        print("start")
rado=Player()#输出start

这说明__init__初始化函数是默认执行的,不能改名
你可以在实例被创建后修改和新增属性

class Player(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
rado=Player("rado",18)
rado.age=19
print(rado.__dict__,type(rado.__dict__))#{'name': 'rado', 'age': 19} <class 'dict'>

__dict__函数会返回所有属性的字典

类属性

区别于之前的实例属性,类属性一般会对实例属性进行统计或限制

class Player(object):
    numbers=0#类属性
    def __init__(self,name,age):
        self.name = name
        self.age = age
        Player.numbers+=1
rado=Player("rado",18)
rado.age=19
print(rado.__dict__)#{'name': 'rado', 'age': 19}
print("欢迎第%d个玩家"%Player.numbers)#欢迎第1个玩家

下面我们综合之前学的内容,编一个可爱类

class cute(object):
    numbers = 0
    levels = ["还行", "好可爱", "化了", "可爱哭了", "此可爱只应理念世界存在"]
    max_cute = 20000

    def __init__(self, name, like, level):
        self.name = name
        self.like = like
        self.level = level
        cute.numbers += 1
        if like > cute.max_cute:
            raise Exception("最大的可爱值是20000,请重试!")
        if level not in cute.levels:
            raise Exception("这样的可爱法律允许但不提倡!")
bingo = cute("bingo", 200000, "挺可爱的")
print(bingo)#输出:Exception: 最大的可爱值是20000,请重试!

结合异常处理的知识改进

class cute(object):
    numbers = 0
    levels = ["还行", "好可爱", "化了", "可爱哭了", "此可爱只应理念世界存在"]
    max_cute = 20000

    def __init__(self, name, like, level):
        self.name = name
        self.like = like
        self.level = level
        cute.numbers += 1
        # if like > cute.max_cute:
        #     raise Exception("最大的可爱值是20000,请重试!")
        if level not in cute.levels:
            raise Exception("这样的可爱法律允许但不提倡!")
try:
    bingo = cute("bingo", 200000, "挺可爱的")
    print(bingo)
    rado=cute("rado", 20000, "cute")
    print(rado)
except Exception as e:
    print(e)

实例方法

就像人类中的每一个人不止具有自己的属性和作为人类的类属性,还要有自己的动作生活,也就是方法

class Player(object):
    numbers=0
    def __init__(self,name,age):
        self.name = name
        self.age = age
        Player.numbers+=1
    def show(self):
        print("Name:",self.name,"Age:",self.age)
rado=Player("rado",18)
rado.show()#Name: rado Age: 18

我们可以把写得两个类结合起来

class cute(object):
    numbers = 0
    levels = ["还行", "好可爱", "化了", "可爱哭了", "此可爱只应理念世界存在"]
    max_cute = 20000

    def __init__(self, name, like, level):
        self.name = name
        self.like = like
        self.level = level
        cute.numbers += 1
        # if like > cute.max_cute:
        #     raise Exception("最大的可爱值是20000,请重试!")
        if level not in cute.levels:
            raise Exception("这样的可爱法律允许但不提倡!")
class Player(object):
    numbers = 0

    def __init__(self, name, age):
        self.name = name
        self.age = age
        Player.numbers += 1

    def show(self):
        print("Name:", self.name, "Age:", self.age)

    def be_cute(self, cute):
        self.cute = cute

    def show_cute(self):
        for k, v in self.cute.__dict__.items():
            print(k, v)

try:
    rado = Player("rado", 18)
    rado_love=cute("rado", 20000, "可爱哭了")
    rado.be_cute(rado_love)
    rado.show_cute()
except Exception as e:
    print(e)

类方法,区别于实例方法

一定要先写装饰器@classmethod,说明这是类方法,于是默认参数也就变了

    @classmethod
    def get_numbers(cls):
class cute(object):
    numbers = 0
    levels = ["还行", "好可爱", "化了", "可爱哭了", "此可爱只应理念世界存在"]
    max_cute = 20000
    all_cute=[]#存放所有like值
    def __init__(self, name, like, level):
        self.name = name
        self.like = like
        self.level = level
        cute.numbers += 1
        if level not in cute.levels:
            raise Exception("这样的可爱法律允许但不提倡!")
        cute.all_cute.append(like)
    @classmethod
    def get_cutiest(cls):#类方法
        cutiest = 0
        for i in cls.all_cute:
            if i > cutiest:
                cutiest = i
        return cutiest
cute1 = cute("saf",2000,"化了")
cute2 = cute("sa",20000,"化了")
print(cute.all_cute)
for i in cute.all_cute:
    print(i)
print(cute.get_cutiest())

静态方法

通常用于写检查项,比如我们在刚才的cute类里加一段这个,就可以不让洋人cute了

@staticmethod
    def isvalid(**kwargs):
        if kwargs["name"].isalpha():
            return False
        else:
            return True

把验证信息储存在字典里

cute_dict={"name":"saf","like":2000,"level":"化了"}
print(cute.isvalid(**cute_dict))#False

面向对象的三大特点

继承

比如程序员就是人类这个类当中的一个子类,她/他具有父类的基本属性,但又有自己的个性
还是用之前的例子

class Player(object):
    numbers = 0

    def __init__(self, name, age):
        self.name = name
        self.age = age
        Player.numbers += 1

    def show(self):
        print("Name:", self.name, "Age:", self.age)

    @classmethod
    def get_numbers(cls):
        print("我们有%d个用户"%cls.numbers)

class VIP(Player):#创建子类
    pass
mia = VIP("mia",24)
print(mia.name, mia.age)#mia 24
print(type(mia))#<class '__main__.VIP'>
print(isinstance(mia, Player))#True
print(isinstance(mia,VIP))#True

我们还可以在子类里重写父类的函数

class VIP(Player):
    def __init__(self, name, age,coin):
        #调用父类的构造函数
        super().__init__(name, age)
        self.coin = coin
    def show(self):#重写实例函数
        print("Name:", self.name, "Age:", self.age,"余额",self.coin)
mia = VIP("mia",24,1000)
print(mia.coin)#1000
mia.show()#Name: mia Age: 24 余额 1000

用子类的函数会优先在子类找,找不到了再看父类

多态

比如在animal这个类里猫和狗都有叫声这个方法,但二者呈现不同

class Animal(object):

    def speak(self):
        print("动物的叫声:")
class Cat(Animal):
    def speak(self):
        print("miaomiao")
class Dog(Animal):
    def speak(self):
        print("wangwang")
        pass

def speak(object):#我们现在需要是Animal类型的实例
    object.speak()#如果传入的类里没有speak那就会报错
animal=Animal()
kitty=Cat()
puppy=Dog()
speak(animal)#这三行体现了多态
speak(kitty)#这三行体现了多态
speak(puppy)#这三行体现了多态

封装

就是不让你看见里面写了啥,就比如你用input,但是你根本不知道它具体是怎么实现的
先来看一种下划线体现命名时的封装

class User():
    def __init__(self,name,age):
        self._name = name#这只是个口头说明,告诉大家这是受保护的变量,但实际不会约束它
        self.__age = age#私有变量,这个约束的就很严格
mia=User('mia',24)
print(mia._name)#打印出来mia
print(mia.__age)#报错AttributeError: 'User' object has no attribute '__age'

如果你给函数命名时也会有这种现象
另外在类里面还是可以用私有变量的
但你依然有办法获取到私有变量,比如像下面这样

class User():
    def __init__(self,name,age):
        self._name = name#受保护的变量
        self.__age = age#私有变量
    def show_infos(self):
        print("Name:",self._name,"Age:",self.__age)
mia=User('mia',24)
# print(mia._name)
# print(mia.__age)
print(mia.__dict__)#{'_name': 'mia', '_User__age': 24}

结果给我们输出了age的真名,那我们就可以用这个名字去调用

print(mia._User__age)#24

我们也可以获取被封装的函数

class User():
    def __init__(self,name,age):
        self._name = name#受保护的变量
        self.__age = age#私有变量
    def __show_infos(self):
        print("Name:",self._name,"Age:",self.__age)
mia=User('mia',24)
print(dir(User))

它输出了['_User__show_infos', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
从中我们找出了_User__show_infos这就是函数的真名


由于我们害怕用户乱改,所以要封装,但又用户又得能改,所以也要提供修改的方法

class User():
    def __init__(self,name,age):
        self._name = name#受保护的变量
        self.__age = age#私有变量
    def get_age(self):#获取
        return self.__age
    def set_age(self,age):#修改
        if isinstance(age,int):#设置规则,不让随便修改
            self.__age =age
        else:
            raise Exception("年龄只能是整数")
mia=User('mia',24)
print(mia.get_age())#24
mia.set_age(25)
print(mia.get_age())#25

但这个修改个年龄的办法有点麻烦了,我们还可以用装饰器进行简化如下

class User():
    def __init__(self,name,age):
        self._name = name#受保护的变量
        self.__age = age#私有变量
    @property#获取变量
    def get_age(self):
        return self.__age
    def set_age(self,age):
        if isinstance(age,int):
            self.__age =age
        else:
            raise Exception("年龄只能是整数")

mia=User('mia',24)

print(mia.get_age)#注意,这里不能写括号了,不能把这个当函数名用了

实际上@property这个装饰器的作用就是把函数变成变量,那我们就可以把它再简化,直接在函数定义的时候把名字改成age

    @property#获取变量
    def age(self):
        return self.__age
……
print(mia.age)#这就可以和之前一样使用这句话了

更进一步,我们用变量的修改器setter简化

class User():
    def __init__(self,name,age):
        self._name = name#受保护的变量
        self.__age = age#私有变量
    @property#获取变量
    def age(self):
        return self.__age
    @age.setter#变量的修改器
    def age(self,age):
        if isinstance(age,int):
            self.__age =age
        else:
            raise Exception("年龄只能是整数")

mia=User('mia',24)

print(mia.age)
mia.age=25
print(mia.age)# 现在就既实现了封装,又实现了和平常一样的逻辑使用
  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值