day16:army小练习、@property、动态添加属性和方法、限制添加属性、__repr__和__str__、类方法和静态方法

一、army小练习

使用面向对象,实现army练习
创建一支军队:骑兵、法师、弓箭手
将军可以下达命令指挥军队

"""
创建一支军队:骑兵、法师、弓箭手
将军可以指挥军队下达命令
"""
class Cavalry:
    def attack(self):
        print("My iron rides on you!")
    def defend(self):
        print("cavalry defend!")
class Archer:
    def attack(self):
        print("My arrow is extremely accurate!")
    def defend(self):
        print("archer defend!")
class Magician:
    def attack(self):
        print("My magic is infinite!")
    def defend(self):
        print("magician defend!")

if __name__ == '__main__':
    army = []
    c = Cavalry()
    m = Magician()
    a = Archer()

    army.append(c)
    army.append(a)
    army.append(m)

    order = input("please order the army:")
    if order == "attack":
        for var in army:
            var.attack()
    elif order == "defend":
        for var in army:
            var.defend()
    elif order == "flatten it":
        for var in army:
            if isinstance(var,Cavalry):
                var.attack()
            else:
                var.defend()
    elif order == "shoot it":
        for var in army:
            if isinstance(var,Archer):
                var.attack()
            else:
                var.defend()
    elif order == "magic it":
        for var in army:
            if isinstance(var,Magician):
                var.attack()
            else:
                var.defend()
    else:
        print("The wind is too hard to hear the order!")
        

运行效果
please order the army:magic it
cavalry defend!
archer defend!
My magic is infinite!

二、@property

把一个方法当做属性来用
例如在方法前加上@property
会导致私有属性去私有化

使用@age.setter注意,三个age,必须是相同的

#把一个方法当做属性来用
class Person:
    def __init__(self,n,age):
        self.name = n
        self.__age = age
    @property
    def age(self):
        return self.__age
    @age.setter #注意,三个age,必须是相同的
    def age(self,n):
        self.__age = n

if __name__ == '__main__':
    p = Person("小红",18)
    print(p.name)
    #通过property可以像属性一样使用
    p.age = 21
    print(p.age) #导致私有属性去私有化

三、动态添加属性和方法

动态添加属性:类内没有的属性,可以直接添加

#动态添加属性
class Person:
    pass
def tell(self):
    print("my name is %s"%self.name)

if __name__ == '__main__':
    p = Person()
    #动态添加一个属性给当前实例,仅限于当前实例访问,其他实例不可以访问
    p.name = "js"
    print(p.name)

动态添加方法
需要引用from types import MethodType
可以将一个类外的函数绑定给对象
tell是要绑定的函数,p是函数绑定到被指定的实例
p.speak = MethodType(tell,p)

#可以把一个方法动态的添加
from types import MethodType

#动态添加属性
class Person:
    pass
def tell(self):
    print("my name is %s"%self.name)

if __name__ == '__main__':
    p = Person()
    #动态添加一个属性给当前实例,仅限于当前实例访问,其他实例不可以访问
    p.name = "js"
    print(p.name)

    #动态添加方法
    #tell是要绑定的函数,p是函数绑定到被指定的实例
    p.speak = MethodType(tell,p)
    p.speak()

四、限制添加属性

在类内添加__slots__ = (“name”,)
可以现在添加属性,注意这里是元祖。

class Person:
    #限制添加属性
    __slots__ = ("name",) #注意这里是元祖,就算只有一个元素也必须要添加逗号
    def __init__(self,name,age):
        self.name = name
        self.age = age

if __name__ == '__main__':
    p = Person("js",11) #AttributeError: 'Person' object has no attribute 'age'

五、repr__和__str

当调用print打印实例的时候,才会调用str
而repr在文件交互模式下输入实例,按下回车的时候会自动调用

class Test:
    def __init__(self,name = "jack",age = 19):
        self.name = name
        self.age = age
class TestStr(Test):
    def __repr__(self):#当str不存在的时候,repr=str
        return "__repr__: %s,%s"%(self.name,self.age)
    def __str__(self):
        return "__str__: %s,%s"%(self.name,self.age)

t = TestStr()
print(t.name)
print(t) #当调用print打印实例的时候,才会调用str

#而repr在文件交互模式下输入实例,按下回车的时候会自动调用

六、类方法和静态方法

它们都可以直接通过类名来调用
在写接口的时候,会使用这样的方法,这样就不用一直创建实例来调用le

class Person:
    #类属性
    name = "jeck"
    def __init__(self,name):
        self.name = name

    def tell(self): #self 接收的是rose
        print(self.name)

    @classmethod
    def say(cls):   #cls接收类,打印类属性
        print(cls.name)

    @staticmethod
    def talk():     #
        print(Person.name)


if __name__ == '__main__':
    p = Person("rose")
    p.tell()    #rose
    p.say()     #jeck
    p.talk()    #jeck

    Person.tell(p)  #rose 这种写法不实用
    Person.say()    #jeck
    Person.talk()   #jeck

练习

class Date:
    def __init__(self,year = 0,month = 0,day = 0):
        self.year = year
        self.month = month
        self.day = day

    def show(self):
        print(self.year,self.month,self.day)

    @staticmethod
    def get_date(string_date):
        year, month, day = string_date.split("-")
        date1 = Date(year,month,day) #这里必须为类名,如果类名变化,也需要变化
        return date1

    @classmethod
    def get_dateL(cls,string_date):
        year, month, day = string_date.split("-")
        date1 = cls(year, month, day) #这里为cls而不是类名,可以随意修改类名
        return date1

if __name__ == '__main__':

    """
    假设用户输入2020-3-13
    """
    t = Date.get_date("2020-3-13")
    t.show()
    t = Date.get_dateL("2020-3-13")
    t.show()

注意:当需要对输入进行分割用split

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值