美文网首页
python+AI第八课

python+AI第八课

作者: M_小七 | 来源:发表于2019-11-19 05:53 被阅读0次
私有属性---封装

在实际开发中,对象的某些属性或方法 可能只希望在对象的内部被使用,而不希望在外部被访问到时就需要封装。
定义属性或方法时,在属性名或者方法名前增加两个下划线__ 代表私有属性,
访问私有属性的方法如下:
1.通过自定义get,set方法提供私有属性的访问

class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    #定义对私有属性的get方法,获取私有属性
    def getAge(self):
        return self.__age

    #定义对私有属性的重新赋值的set方法,重置私有属性
    def setAge(self,age):
        self.__age = age

person1 = Person("tom",19)
person1.setAge(20)
print(person1.name,person1.getAge())  #tom 20

2.使用property标注提供私有属性的访问

class Teacher:
    def __init__(self, name, age,speak):
        self.name = name
        self.__age = age
        self.__speak = speak


    @property      # ‘装饰器’ 注意1.@proterty下面默认跟的是get方法,如果设置成set会报错。
    def age(self):
        return self.__age

    @age.setter    #注意2.这里是使用的上面函数名.setter,不是property.setter.
    def age(self,age):
        if age > 150 and age <=0:  #还可以在setter方法里增加判断条件
            print("年龄输入有误")
        else:
            self.__age = age

    @property
    def for_speak(self):  #注意2.这个同名函数名可以自定义名称,一般都是默认使用属性名。
        return self.__speak

    @for_speak.setter
    def for_speak(self, speak):
        self.__speak = speak

t1 = Teacher("herry",45,"Chinese")
t1.age = 38    #注意4.有了property后,直接使用t1.age,而不是t1.age()方法了。
t1.for_speak = "English"  

print(t1.name,t1.age,t1.for_speak)  #herry 38 English
将实例用作属性---对象组合

使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分属性和方法作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类
例子1:
需求
房子(House) 有户型、总面积和家具名称列表
新房子没有任何的家具
家具(HouseItem) 有 名字 和 占地面积,其中
席梦思(bed) 占地 4 平米
衣柜(chest) 占地 2 平米
餐桌(table) 占地 1.5 平米
将以上三件 家具 添加 到 房子 中
打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表
剩余面积

在创建房子对象时,定义一个 剩余面积的属性,初始值和总面积相等
当调用 add_item 方法,向房间 添加家具 时,让 剩余面积 -= 家具面积
先定义一个家具类

class HoureItem:
    def __init__(self,name,area):
        self.name = name
        self.area = area

    # def __str__(self):
    #     return f'{self.name}占地面积{self.area}平方米'

    def __repr__(self):
        return f'{self.name}占地面积{self.area}平方米'
if __name__ == '__main__':
    bed = HoureItem('席梦思',4)
    chest = HoureItem('衣柜',2)
    table = HoureItem('餐桌',1.5)

再定义一个猫类

class Cat:
    def __init__(self,color,name):
        self.color = color
        self.name = name
        # print('__init__')
    def __str__(self):
        return self.color + '的' + self.name
    def eat(self):
        print(f'{id(self)}号小猫在吃鱼,我的名字是{self.name}')
    def drink(self):
        print(f'{id(self)}号小猫在喝水')

if __name__ == '__main__':
    cat1 = Cat('褐色','英短')
    cat2 = Cat('蓝色','大懒猫')
    print(cat1)
    print(cat2)

最后定义一个house类,并调用之前定义的家具和猫类

from Cat import Cat
from HoureItem import HoureItem
class House:
    def __init__(self,type,area):
        self.type = type
        self.area = area
        self.remain_area = area
        #self.house_items保存的是HouseItem类型的对象
        self.house_items = []
        self.pet = None

    def __str__(self):
        return f"户型:{self.type}  总面积:{self.area}[剩余:{ self.remain_area}]\n家具:{self.house_items}"

    def take_pet(self,pet):
        self.pet = pet

    def add_item(self,house_item):
        self.house_items.append(house_item)
        self.remain_area -= house_item.area

bed = HoureItem('席梦思',4)
chest = HoureItem('衣柜',2)
table = HoureItem('餐桌',1.5)

house = House('三室一厅',123)
print(house)
print('-'*70)
house.add_item(bed)
house.add_item(chest)
house.add_item(table)
print(house)

cat2 = Cat('蓝色','大懒猫')
house.take_pet(cat2)
'''
户型:三室一厅  总面积:123[剩余:123]
家具:[]
----------------------------------------------------------------------
户型:三室一厅  总面积:123[剩余:115.5]
家具:[席梦思占地面积4平方米, 衣柜占地面积2平方米, 餐桌占地面积1.5平方米]
'''

例子2:英雄pk怪物

from random import randint
class Hero:
    def __init__(self, name, blood, strength):
        """

        :param name:
        :param blood:
        :param strength:
        """
        self.name = name
        self.blood = blood
        self.strength = strength

    def calc_health(self):
        return self.blood

    def take_damage(self, monster):
        damage_point = randint(monster.strength - 10, monster.strength + 10)
        self.blood -= damage_point
        if self.blood < 0:
            self.blood = 0
        print(f"{self.name}你被{monster.name}攻击,受到了{damage_point}点伤害!还剩{self.blood}滴血")
        if self.blood > 0:
            return False
        else:
            print(f"{self.name}你被杀死了!胜败乃兵家常事 请重新来过。")
            return True

from random import randint
class Monster:
    def __init__(self, name,blood,strength):
        self.name = name
        self.blood = blood
        self.strength = strength

    def calc_health(self):
        return self.blood

    def take_damage(self, hero):
        damage_point = randint(hero.strength - 5, hero.strength + 5)
        self.blood -= damage_point
        if self.blood < 0:
            self.blood = 0
        print(f"{self.name}你被{hero.name}攻击,受到了{damage_point}点伤害!还剩{self.blood}滴血")
        if self.calc_health() <= 0:
            print(f"{self.name}你被杀死了!胜败乃兵家常事 请重新来过。")
            return True
        else:
            return False

from Hero import Hero
from Monster import Monster

hero = Hero('周瑜',100, 10)
monster = Monster('黄盖',60,20)

while True:
    is_monster_died = monster.take_damage(hero)
    if is_monster_died:
        break
    is_hero_died = hero.take_damage(monster)
    if is_hero_died:
        break
类属性 类方法 静态方法

类属性
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++、Java中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问

# 类属性  
class people:  
    name="Tom"    #公有的类属性  
    __age=18      #私有的类属性  

p=people()  
print(p.name)   #实例对象  
print(people.name)  #类对象  

# print(p.__age)    #错误 不能在类外通过实例对象访问私有的类属性  
print(people.__age) #错误 不能在类外同过类对象访问私有的类属性

类属性应用

class NeuEduClass:
    class_num = 0

    def __init__(self):
        self.class_name = f'东软睿道Python{NeuEduClass.class_num+1}班'
        NeuEduClass.class_num += 1


classList = [NeuEduClass() for i in range(10)]
for c in classList:
    print(c.class_name)

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

class people:  
    country="china"  

    @classmethod  
    def getCountry(cls):  
        return cls.country  

p=people()  
print(p.getCountry())   #实例对象调用类方法  
print(people.getCountry())  #类对象调用类方法

静态方法

class people3:  
    country="china"  

    @staticmethod  
    def getCountry():  
        return people3.country  

p=people3()  
print(p.getCountry())   #实例对象调用类方法  
print(people3.getCountry())  #类对象调用类方法
继承

继承的概念:子类自动拥有(继承)父类的所有方法和属性

class Cat:
    def __init__(self,color,name):
        self.color = color
        self.name = name
        # print('__init__')
    def __str__(self):
        return self.color + '的' + self.name
    def eat(self):
        print(f'{id(self)}号小猫在吃鱼,我的名字是{self.name}')

    def drink(self):
        print(f'{id(self)}号小猫在喝水')


class BosiCat(Cat):
    def eat(self,fish):
        print('波斯猫爱吃螃蟹')

    def catch_mouse(self):
        print(f'{self.name}抓到了一只老鼠')



if __name__ == '__main__':

    cat1 = BosiCat('褐色','xiaohua')
    cat1.eat('ddd')
import math
class Shape:
    def __init__(self,color):
        self.color = color
    def area(self):
        return None
    def show_color(self):
        print(self.color)

class Circle(Shape):
    def __init__(self, color, r):
        super().__init__(color)
        self.r = r
    def area(self):
        return math.pi * self.r * self.r


class Rectangle(Shape):
    def __init__(self,height,width,color):
        self.width = width
        self.height = height
        super().__init__(color)
        # Shape.__init__(self,color)

    def area(self):
        return self.width*self.height


class Square(Rectangle):
    def __init__(self,edge_len,color):
        super().__init__(edge_len,edge_len,color)
        self.edge_len = edge_len

    def area(self):
        return self.edge_len * self.edge_len



circle = Circle('white',10)
print(circle.area())
circle.show_color()

rect = Rectangle(10,12,'black')
print(rect.area())
rect.show_color()

square = Square(10,'red')
print(square.area())
square.show_color()

lst = []
lst.append(circle)
lst.append(rect)
lst.append(square)

for shape in lst:
    print(shape.area())

修改PK游戏
我们发现Hero类和Monster类中有很多代码是重复的,我们把这些重复的代码提取到一个父类Sprite(精灵)中。 sprite.py

from random import randint


class Sprite:

    def __init__(self, flood,strength):
        self.flood = flood
        self.strength = strength

    def calc_health(self):
        return self.flood

    def take_damage(self, attack_sprite):
        damage = randint(attack_sprite.strength - 5, attack_sprite.strength + 5)
        self.flood -= damage
        print(f"{self.name}你被{attack_sprite.name}攻击,受到了{str(damage)}点伤害!还剩{str(self.flood)}滴血")
        if self.calc_health() <= 0:
            print(f"{self.name}你被杀死了!胜败乃兵家常事 请重新来过。")
            return True
        else:
            return False
from sprite import Sprite
class Hero(Sprite):
    def __init__(self, name,flood,strength):
        self.name = name
        super().__init__(flood,strength)
from sprite import Sprite
class Monster(Sprite):
    def __init__(self, name,flood,strength):
        self.name = name
        super().__init__(flood, strength)
from hero import Hero
from monsters import Monster

hero = Hero('张三',100, 10)
monster = Monster('小强',60,20)

while True:
    is_monster_died = monster.take_damage(hero)
    if is_monster_died:
        break
    is_hero_died = hero.take_damage(monster)
    if is_hero_died:
        break

new方法
python中定义的类在创建实例对象的时候,会自动执行init()方法,但是在执行init()方法之前,会执行new()方法。

new()的作用主要有两个
1.在内存中为对象分配空间
2.返回对象的引用。

作业:扑克牌模拟
任务目的
0.培养编程思维,提高分析问题能力
1.掌握类的抽象与设计
2.掌握循环,分支条件的用法
3.掌握各种集合类的使用
任务描述
1.定义一个单张扑克类(考虑需要哪些属性),定义一个一副扑克牌类,该类包含一个单张扑克对象的数组(不考虑大小王)。实现一个模拟扑克发牌洗牌的算法; 2.电脑随机发出5张牌,判断是以下哪种牌型?(提示,利用各种集合的特性可以简化判断)

Card.py


class Card:
    def __init__(self,color,value):
        self.value = value
        self.color = color

    def __repr__(self):
        strvalue = str(self.value)
        if self.value == 11:
            strvalue = 'J'
        if self.value == 12:
            strvalue = 'Q'
        if self.value == 13:
            strvalue = 'K'
        if self.value == 1:
            strvalue = 'A'

        return self.color + strvalue


if __name__ == '__main__':
    cardA = Card('红桃',1)
    print(cardA)


Poke.py

from Card import Card
import random
color_tuple = ('红桃','方片','草花','黑桃')

class Poke:
    def __init__(self):
        self.cards = []

        for color in color_tuple:
            for value in range(1,14):
                card = Card(color,value)
                self.cards.append(card)

    def output(self):
        index = 1
        for card in self.cards:
            print(card,end='\t')
            if index % 13 == 0:
                print()

            index+=1



if __name__ == '__main__':
    poke = Poke()
    poke.output()
    random.shuffle(poke.cards)
    print('-'*70)
    poke.output()
    hands = poke.cards[:5]
    # hands[0] = poke.cards[13]
    print(hands)

    colorsLst = [card.color for card in hands]
    print(colorsLst)
    colorset = set(colorsLst)
    print(colorset)

    valueLst = [card.value for card in hands]
    print(valueLst)
    valueset = set(valueLst)
    print(valueset)
    valueLstSorted = sorted(valueLst)
    print(valueLstSorted)

    bIsSameColor = False
    bIsShunzi = False

    if len(valueset) == 5 and valueLstSorted[-1] - valueLstSorted[0] == 4:
        bIsShunzi = True

    if len(colorset) == 1:
        bIsSameColor = True

    if bIsSameColor == True and bIsShunzi == True:
        print('同花顺')
    elif bIsShunzi:
        print('顺子')
    elif bIsSameColor:
        print('同花')
    elif len(valueset) == 4:
        print('一对')
    elif len(valueset) == 5:
        print('杂牌')
    #4带1或者3带2
    elif len(valueset) == 2:
        if valueLst.count(valueLst[0]) == 1 or valueLst.count(valueLst[0]) == 4:
            print('4带1')
        else:
            print('3带2')
    #311或221
    else:
        isThreeOneOne = False
        for value in valueLst:
            if valueLst.count(value) == 3:
                isThreeOneOne = True
                break

        if isThreeOneOne == True:
            print('311')
        else:
            print('221')

相关文章

网友评论

      本文标题:python+AI第八课

      本文链接:https://www.haomeiwen.com/subject/bqjjictx.html