Python-学习之路-08 OOP -03

类的成员描述符(属性)

  • 类的成员描述符是为了在类中对类的成员属性进行相关操作而创建的一种方式
  • 成员描述符的三种操作
    • get:获取属性的操作
    • set:修改或添加属性操作
    • delete:删除属性操作
  • 如果想使用类的成员描述符,大概有三种方法
    • 使用类实现描述器
      • 适合多个类中多个属性共有一个描述符
    • 使用属性修饰符
      • 在当前类中使用,控制一个类中的一个属性
    • 使用property
      • 在当前类中使用,可以控制一个类中多个属性
      • 无论那种修饰符都是为了对成员属性进行控制
# 使用property 案例
class Person():
    
    def fget(self):
        return self._name*2
    
    def fset(self,name):
        self._name = name.upper()
        
    def fdel(self):
        self._name = "NoName"
    
    name = property(fget,fset,fdel,"property")
    
tom = Person()
tom.name = "tom"
print(tom.name)
TOMTOM

类的内置属性

__dict__:以字典的形似现实类的成员组成
__doc__: 获取类的文档信息
__name__:获取类的名称,如果在模块中使用,获取模块的名词
__bases__:获取某个类的所有父亲,以元组的方式显示

类的常用魔术方法

  • 魔术方法就是不需要人为调用,基本是在特定时刻自动触发
  • 统一特征:方法名被前后两个下划线包裹
    • 典型的魔术方法:'init'
    • 'new' : 对象实例化方法,此函数较为特殊,一般情况下不使用
    • 'call' : 对象当函数使用的时候触发
    • 'str' : 对象当字符串使用的时候触发
    • 'repr': 返回字符串
  • 描述符相关
    • 'set'
    • 'get'
    • 'delete'
  • 属性操作相关
    • 'getattr':访问不存在的属性时触发
    • 'setattr': 对成员属性进行设置的时候触发
      • 参数
        • self用来获取当前对象
        • 被设置属性的名称,以字符串形式出现
        • 需要对属性设置的值
      • 作用:对属性设置的时候进行验证或修改
      • 注意:在该方法中不能对属性直接信息赋值操作,否则会出现死循环
# __call__
class A():
    def __init__(self):
        print("我被调用了")
    
    def __call__(self):
        print("call.....")
        
a = A()
a()
我被调用了
call.....
# __str__
class A():
    def __init__(self):
        print("我被调用了")
    
    def __call__(self):
        print("call.....")
    
    def __str__(self):
        return "str调用"
        
a = A()
print(a)
我被调用了
str调用
# __getattr__
class A():
    name = "NoName"
    age = 19
    def __getattr__(self,name):
        print("没找到啊没找到!!!")
        
a = A()
print(a.add)
没找到啊没找到!!!
None
# __setattr__
class Person():
    def __init__(self):
        pass
    
    def __setattr__(self,name,value):
        #不能直接对属性进行赋值
        #self.name = value 这个是错误的 会导致死循环
        super().__setattr__(name,value)
        print("对属性{0}的赋值为{1}".format(name,value))
        
tom = Person()
tom.name = "tom"

对属性name的赋值为tom
  • 运算类相关魔术方法(这里不一一举例)
    • 'gt':进行大于判断的时候触发
      • 参数:
        • self:对象本身
        • 另一个对象(只要对比的两个对象都包含需要对比的属性即可,不必是两个相同的对象)
        • 返回值:任意值,但是推荐返回布尔值
# __gt__
class Person():
    def __init__(self,name):
        self._name = name
        
    def __gt__(self,obj):
        return self._name >obj._name
    
class Person1():
    def __init__(self,name,age):
        self._name = name
        
    
tom = Person("tom")
jack = Person1("jack",19)
print(tom > jack)
True

类和对象的三种方法

  • 实例方法
    • 需要实例化对象才能使用方法,使用过程中可能需要借助对象的其他方法完成
  • 静态方法
    • 不需要实例化,通过类直接调用(适用与各种工具类,方便直接调用)
  • 类方法
    • 不需要实例化
# 类和对象的三种方法
class Person():
    age = 18
    def __init__(self,name):
        print("my name is {0}".format(name))
        self.name = name
    # 实例方法
    def eat(self):
        #请注意下面的打印信息,<__main__.Person object at 0x7f9f8eb23cc0> 表示当前self是一个实例
        print(self)
        print("{0}正在吃饭!".format(self.name))
    
    #类方法
    #类方法的一个参数一般命名对cls,用于区别与cls
    #
    @classmethod
    def play(cls):
        #请注意下面的打印信息,<class '__main__.Person'>表示当前cls是一个对象,还没有进行实例化,不是一个实例,所以name属性不能用,只能用定义的类属性 age
        print(cls)
        print("TA现在{0}岁了,可以玩这个了!".format(cls.age))
        
    #静态方法
    #不需要用第一个参数表示自身或类 因为自身还没有实例化啊
    @staticmethod
    def sleep():
        #此时就连init都没有被调用所以下面的输出会报错,说name没有被定义
        #print("{0}正在睡觉!".format(name))
        print("sleeping.........")
        
#静态方法的调用
Person.sleep()
#类方法 调用1
Person.play()
#类方法 调用2
p = Person("tom")
p.play()

#实例方法
p.eat()
sleeping.........
<class '__main__.Person'>
TA现在18岁了,可以玩这个了!
my name is tom
<class '__main__.Person'>
TA现在18岁了,可以玩这个了!
<__main__.Person object at 0x7f9f8eb2bd30>
tom正在吃饭!
# 类方法实例
'''
假设我有一个学生类和一个班级类,想要实现的功能为:
    执行班级人数增加的操作、获得班级的总人数;
    学生类继承自班级类,每实例化一个学生,班级人数都能增加;
    最后,我想定义一些学生,获得班级中的总人数。

思考:这个问题用类方法做比较合适,为什么?因为我实例化的是学生,
但是如果我从学生这一个实例中获得班级总人数,在逻辑上显然是不合理的。
同时,如果想要获得班级总人数,如果生成一个班级的实例也是没有必要的。
'''
class ClassTest(object):
    __num = 0

    @classmethod
    def addNum(cls):
        cls.__num += 1

    @classmethod
    def getNum(cls):
        return cls.__num

    # 这里我用到魔术函数__new__,主要是为了在创建实例的时候调用人数累加的函数。
    def __new__(self):
        ClassTest.addNum()
        return super(ClassTest, self).__new__(self)


class Student(ClassTest):
    def __init__(self):
        self.name = ''

a = Student()
b = Student()
print(ClassTest.getNum())
2
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,746评论 2 9
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 家长群里,老师发通知,本周休息时间提前一天,让孩子们开心过冬至。 赶快打开日历看看,周六就是。孩子们上寄宿学校,要...
    叶知风语阅读 239评论 0 1
  • 我遇到一个问题,就是无法找到gem,网上找到解决办法,配置如下:
    chenge微博谈阅读 250评论 0 2
  • 常常听到别人讲,命运决定一切,你的生活取决于你的命运。其实我并不赞同这句话,因为我觉得人生是你自己的生活是自己的,...
    Jenny_佳一阅读 267评论 0 1