属性,类方法,静态方法

(1)将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

(2)由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

示例:

class People:
    def __init__(self,name,age,sex):
        self.name = name
        self.__age = age
        self.__sex = sex

    @property    # property装饰器将类中的方法封装成了属性
    def age(self):
        return self.__age

    @age.setter      # 被 方法名.setter这种装饰器装饰的方法,会在对象对类中的静态变量或属性修改时自动执行的
    def age(self,new_age):
        if type(new_age) is int:
            self.__age = new_age

    @age.deleter     # 被 方法名.deleter这种装饰器装饰的方法,会在对象对类中的静态变量或属性删除时自动执行的
    def age(self):
        print(self.__age)

p = People('eric',33,'')
print(p.age)

p.age = 21  # p.age中,p是对象名,age其实是类中的方法名,并不是类中的属性名
print(p.age)
del p.age
View Code

练习题

class Commodity:
    def __init__(self,name,price,discount):
        self.name = name
        self.__price = price
        self.__disconut = discount

    @property
    def price(self):
        return self.__price * self.__disconut

    @price.setter
    def price(self,new_price):
        self.__price = new_price

c = Commodity('banana',7.5,0.4)
print(c.price)

 

c.price = 9

print(c.price)
View Code

类方法

(1)一般是由类名调用,有些情况,对于类内部的方法,无需对象直接调用,而类名直接调用即可。

class People:
    chara = '有思想'

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

    def drink(self):
        return '%s正在和水'%self.__name

    @property
    def hobby(self):
        print('%s的爱好是大保健'%self.__name)

    @classmethod
    def hobby(cls,now_hobby):
        cls.__hobby = now_hobby
        return cls.__hobby

p = People('eric',23)、
print(People.hobby('上山砍柴'))
View Code

静态方法

(1)不需要传入类名或对象名,直接调用即可

class Animal:
    chara = '有意识'

    @staticmethod
    def cat(name,sex):
        print('有一只猫,名字叫%s,它今年有%s岁了,已经很老了' %(name,sex))
Animal.cat('阿花',18)
View Code

反射

反射:getattr*****、hasattr*****、setattr**、delattr*的使用

1、反射的概念:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

2、四个可以实现自省的函数(下列方法适用于类和对象,一切皆对象,类本身也是一个对象)

 

普通情况下:

msg = input('>>>').strip()
class Animal:
    role = '铲屎官'
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
 
    def cat(self):
        print('一只大花猫叫阿花')
通过input输入的方式获取一个字符串,然后获取到类中的对应的值,但是普通情况下会有问题

print(Animal.msg)  # 报下面的错误
>>>role
Traceback (most recent call last):

  File "C:/Users/admin/PycharmProjects/xu/s22day07/05 反射.py", line 17, in <module>
    print(Animal.msg)

AttributeError: type object 'Animal' has no attribute 'msg'

因为input输入的内容是一个字符串,通过类名.变量名或类名.方法名中.后面的内容不能是字符串类型。
取到值的办法:
print(Animal.__dict__[msg])  # __dict__最好只用在通过类名或对象名去查内容,而不是去取值
>>>role
铲屎官
View Code

1、在类中

msg = input('>>>').strip()
class Animal:
    role = '铲屎官'

    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def cat(self):
        return '一只大花猫叫阿花'

c = Animal('阿花',18,'male')

(1)hasattr 判断类中是否有想要的方法
print(hasattr(Animal,'cat')) # True
print(hasattr(Animal,'dog')) # True

(2)getattr 获取值
print(getattr(Animal,msg))  # getattr的括号中,前面可以是类名,对象名,后面则必须是字符串类型,类中的变量名或者方法名在getattr中都要变成字符串类型,而msg的结果就是一个字符串类型,所以能执行成功。
>>>role
铲屎官

print(getattr(Animal,'cat')(1))  # cat是类中的一个方法,也是一个函数,getattr(Animal,'cat')取到的是cat这个函数的内存地址,后面加个()就能运行,但是因为cat函数里面有个self,所以要随便传一个值给这个self。

(3)hasattr 判断
print(hasattr(Animal,msg))  # True

if hasattr(Animal,msg) and msg == 'cat':
    print(getattr(Animal,msg)(1))
elif hasattr(Animal,msg):
    print(getattr(Animal, msg))
else:
    print('输入错误')

(4)setattr 增加或修改
setattr(Animal,'arms','AK47')  # 增加新值
print(Animal.__dict__)  # 查看
'arms': 'AK47'

setattr(Animal, 'role', '汪星人')
print(Animal.__dict__)
'role': '汪星人',

(5)delattr  删除
delattr(Animal,'role')
print(Animal.__dict__)
View Code

2、对象中

msg = input('>>>').strip()

class Animal:
    role = '铲屎官'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def cat(self):
        print('一只大花猫叫阿花')

c = Animal('阿花', 18, 'male')

(1)getattr
getattr(c,msg)()  # 加括号执行方法
print(getattr(c,msg))  # 取静态变量的值

(2)hasattr
print(hasattr(c,'role'))
print(hasattr(c,'cat'))
print(hasattr(c,'dog'))  # False

(3)setattr
setattr(c,'name','大黄')
print(c.__dict__)
{'name': '大黄', 'age': 18, 'sex': 'male'}

(4)delattr
delattr(c,'sex')
print(c.__dict__)
{'name': '大黄', 'age': 18, 'sex': 'male'}
View Code

3、模块中

import oy # 自定义模块
方式1
a = getattr(oy,'A')()  # 取模块中类的内存地址,赋值给一个变量,生成一个对象
getattr(a,'func1')()    # 通过对象名执行类里面的方法
print(getattr(a,'role'))  # 取变量

方式2
print(getattr(oy,'A').role)  # 通过A的内存地址直接加.role取值
getattr(oy,'A').func1(1)  # 通过内存地址直接取方法的值

方式3
print(getattr(getattr(oy,'A'),'role'))
getattr(getattr(oy,'A'),'func1')(1)
View Code

4、当前模块中

port sys
class Animal:
    role = '铲屎官'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def cat(self):
        print('一只大猫叫阿花')

print(getattr(getattr(sys.modules[__name__],'Animal'),'role'))
g = getattr(sys.modules[__name__],'Animal')
getattr(g,'cat')(1)
View Code

 

posted on 2018-06-29 11:01  花豆豆  阅读(400)  评论(0编辑  收藏  举报