2019-05-25

Python录屏学习

  • 定义类
    class()
  • 类的属性
    self.属性名 是实例属性
  • 类的方法
  • 创建实例
  • 类本身就是一个实例,可以对其进行操作
  • 再类里直接定义的属性,称为类属性,类属性由所有对象共享.
    可以创建类的属性,然后作为一个共享的属性
class C:
    num=0
    def __init__(self):
        self.name="ss"
        C.num+=1
        print(C.num)
    def print_num(self):
        print(C.num)
c0=C()
c1=C()
c2=C()
C.num+=1
c2.print_num()
#1
#2
#3
#4
  • 属性私有化
    1. 两个下划线开头
__name

为什么双下划线不能访问
在 实例.dict 中,保存着实例的一些属性,当用双下划线命名时,后台将名字更改了,原来dict里面装的实例的属性,双下划线开头的属性,会被转换为:_类名+属性名。比如原来的“_name”,被后台改为了“类名__name”。实际上如果了解了更改的规则的话,还是能更改的。

  1. 单下划线开头,约定的,不能真正的无法更改
_name
  • 属性的更改及检查有效性
    通常直接给属性赋值时,无法检查赋值的有效性,因此常属性前面加两个下滑线,使之变为不可改变的属性,之后创建更改属性的方法,并在方法里加入检查赋值有效性的语句.这样既能让属性可以修改,同时也保证了对赋值有效性的检查.
class Student:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age

    def set_name(self,name):
        if not len(name)<3:
            self.name=name

    def get_name(self):
        return self.__name

这种使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。
但是写 s.get_score() 和 s.set_score() 没有直接写 s.score 来得直接。

有没有两全其美的方法?----有。

@property 装饰器 和@属性名.setter

因为Python支持高阶函数,在函数式编程中我们介绍了装饰器函数,可以用装饰器函数把 get/set 方法“装饰”成属性调用:

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    @property
    def score(self):
        return self.__score
    @score.setter
    def score(self, score):
        if score < 0 or score > 100:
            raise ValueError('invalid score')
        self.__score = score

看上面代码可知,把get方法变为属性只需要加上@property装饰器即可,此时@property本身又会创建另外一个装饰器@score.setter,负责把set方法变成给属性赋值,这么做完后,我们调用起来既可控又方便

注意: 第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。

现在,就可以像使用属性一样设置score了:

>>> s = Student('Bob', 59)
>>> s.score = 60
>>> print s.score
60
>>> s.score = 1000
Traceback (most recent call last):
  ...
ValueError: invalid score

说明对 score 赋值实际调用的是 set方法。

@staticmethod和@classmethod的用法

不用实例化就直接调用类的方法.

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。
下面上代码。

class A(object):  
    bar = 1  
    def foo(self):  
        print 'foo'  

    @staticmethod  
    def static_foo():  
        print 'static_foo'  
        print A.bar  

    @classmethod  
    def class_foo(cls):  
        print 'class_foo'  
        print cls.bar  
        cls().foo()  
###执行  
A.static_foo()  
A.class_foo()  

输出
static_foo
1
class_foo
1
foo

继承

继承父项的属性

class A:
    def __init__(self):
        self.name="A"

class B:
    def __init__(self):
        self.name="B"

class C(A):
    pass

c=C()

print(c.name)
#A

super().init() 若有自己的属性,又想继承父项属性

要在自己的init中加入super().init()

没写super().init() 的情况

#没写super().__init__() 的情况
class A:
    def __init__(self):
        self.name="A"

class B:
    def __init__(self):
        self.name="B"

class C(A):
    def __init__(self):
        self.age=12
    
c=C()

print(c.name)
#AttributeError: 'C' object has no attribute 'name'

写了super().init() 的情况

class A:
    def __init__(self):
        self.name="A"

class B:
    def __init__(self):
        self.name="B"

class C(A):
    def __init__(self):
        super().__init__()
        self.age=12

c=C()

print(c.name)
#A

多继承

多继承会导致程序混乱,尽量不要使用
所有类都会默认继承subject类

如果继承的两个父项中有相同的内容,则按顺序优先

class A:
    def __init__(self):
        self.name="A"

class B:
    def __init__(self):
        self.name="B"

class C(A,B):
    def __init__(self):
        super().__init__()
        self.age=12

c=C()

print(c.name)
#A
  • C.mro 查看继承顺序
class A:
    def __init__(self):
        self.name="A"

class B:
    def __init__(self):
        self.name="B"

class C(A,B):
    def __init__(self):
        super().__init__()
        self.age=12

c=C()
print(C.__mro__)
#(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
  • 如果是类的类成员,排序在父项之后
class A:
    def __init__(self):
        self.name="A"

class B:
    def __init__(self):
        self.name="B"

class C(A,B):
    name="C"
    def __init__(self):
        super().__init__()
        self.age=12

c=C()

print(c.name)
#A

对父项方法的调用

class A:
    def __init__(self):
        self.name="A"

    def print_a(self):
        print("aaaaa")

class B:
    def __init__(self):
        self.name="B"

class C(A,B):
    name="C"
    def __init__(self):
        super().__init__()
        self.age=12

c=C()

c.print_a()
#aaaaa
  • 对父项方法的调用并加上自己的改造
class A:
    def __init__(self):
        self.name="A"

    def print_a(self):
        print("aaaaa")

class B:
    def __init__(self):
        self.name="B"

class C(A,B):
    name="C"
    def __init__(self):
        super().__init__()
        self.age=12

    def print_a(self):
        super().print_a()
        print("a-a-a")

c=C()

c.print_a()
#aaaaa
#a-a-a

用组合实现继承的功能

程序中除非对继承很清楚,最好用组合来替代

class A:
    def __init__(self):
        self.name="A"

    def print_a(self):
        print("aaaaa")

class B:
    def __init__(self):
        self.name="B"

class C(A,B):
    name="C"
    def __init__(self):
        super().__init__()
        self.age=12

    def print_a(self):

        print("a-a-a")

class D:
    def __init__(self):
        self.a=A()

    def print_a(self):
        self.a.print_a()
        print('d_a_a')

d=D()
d.print_a()
#aaaaa
#d_a_a

isinstance(c,C)判断是不是某个类的实例

这对自己的类,和父项,都输出True

issubclass(C,A)判断是不是子类

语法糖

https://blog.csdn.net/five3/article/details/83474633
语法糖(Syntactic sugar):
计算机语言中特殊的某种语法
这种语法对语言的功能并没有影响
对于程序员有更好的易用性
能够增加程序的可读性

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