面向对象

实例变量 & 类变量

class Role(object):
    # <类变量> = var
    n = 100
    n_list = []
    name = 'hahaha'
    def __init__(self, var):
        # self.<实例变量> = var
        self.name = var

>>>r1 = Role(var='lalala')
>>>r1.name
lalala
>>>Role.name
hahaha

>>>r2 = Role('lex')
>>>r2.n
100
>>>r1.n = 200
>>>r1.n
200
>>>r2.n
100
# 其实在r1的内存里创建了变量 n=200,类变量没动

# r1,r2,Role 都公用一个内存变量 n_list
>>>r1.n_list.append("from r1")
>>>r2.n_list.append("from r2")
>>>r2.n_list
["from r1","from r2"]
>>>Role.n_list
["from r1","from r2"]

析构函数

在实例释放、销毁的时候自动执行
del var 启动 __del__(self)方法
摘掉门牌号,自动回收机制删除内存

私有方法、私有属性

加俩下划线:self.life_value ---> self.__life_value
外界无法直接访问,可以内部定义一个方法访问

类的封装

封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法。

简单的说,将外部函数内部化为类的方法,就是封装。

新式类 & 经典类

"""  Author: Dr.Ch  """


# class People:  ## 经典类写法
class People(object):  # 新式类  ## object是个基类

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

    def eat(self):
        print("%s is eating..." % self.name)

    def talk(self):
        print("%s is talking..." % self.name)

    def sleep(self):
        print("%s is sleeping..." % self.name)


class Relation(object):  # 给人加上社交属性

    def make_friends(self, obj):  # obj 是 其他人,尚未实例化的
        print("%s is making friends with %s" % (self.name, obj.name))


class Man(People, Relation):  # 注释1

    # 为了增加子类属性,需要重构 __init__()
    def __init__(self, name, age, money):  # 增加属性:男人出生就有钱
        # 把父类的属性拿过来
        People.__init__(self, name, age)  # 经典类写法
        self.money = money
        print("%s 一出生就有 %s money" % (self.name, self.money))

    def whoring(self):  # 定义子类新方法
        print("%s is whoring..." % self.name)

    def sleep(self):
        print("man is sleeping...")  # 更改父类方法

    def talk(self):
        People.talk(self)  # 直接调用父类方法

    def eat(self):
        People.eat(self)
        print("man is eating...")  # 在父类方法上增加新功能


class Woman(People, Relation):

    def __init__(self, name, age, height, big_breast=True):
        # 另一种高级的方法继承父类,代替 line32 的语法
        super(Woman, self).__init__(name, age)  # 新式类写法  ## 注释2
        self.height = height
        self.big_breast = big_breast

    def get_birth(self):
        print("%s is born a baby..." % self.name)


print("\n--------- 多继承 -----------")
m3 = Man("Jon", 25, 2000)
w3 = Woman("Maria", 22, 170, False)
m3.make_friends(w3)

print("\n--------- women -----------")
w1 = Woman("alex", 22, 162)
w1.get_birth()

print("\n--------- men -----------")
m1 = Man("lex", 23, 20)
m1.whoring()
m1.sleep()
m1.talk()
m1.eat()

print("\n--------- men 继承 -----------")
m2 = Man("clark", 24, 100)

print("\n--------- women 继承 -----------")
w2 = Woman("lana", 21, 165)


"""
注释1:Man的实现 先在Man里面执行__init__()生成 name ,再继承Relation的方法,所以name已经有了
       不是在People里面执行__init__(),所以 Man(People,Relation)继承顺序无影响。
       如果没有自己的构造方法,应该去执行父类的__init__(),然而依然没有报错(Relation,People),
       因为make_friends()还没有执行。
       ……总之按照从左到右顺序继承。(见视频30分钟处)
       对象生成,先实例化,多继承的时候,从左到右: SubClass(Class1,Class2,...,ClassN):
       先执行 SubClass 的 构造函数__init__(),如果没有构造函数,则
       执行 Class1 的 构造函数,如果 Class1 也没有 构造函数,则
       执行 Class2 的 构造函数,…… 以此类推。重点是,只继承一个就结束。
       
       —— 关于广度优先、深度优先见视频6.9 10分钟左右——(面试必备)
       A,B(A),C(A),D(B,C)
       py2 是深度优先:D先继承B,再继承A,最后继承C
       py3 经典类和新式类都是统一按照广度优先来继承的:D先继承B,再继承C,最后继承A

注释2:与 People.__init__(self, name, age) 相比优点在于,
       super(Woman,self).__init__(name, age) 不用写父类名 People,
       如果有一天 People 名字改了,只需要改一次 line50 处
       另外,有利于多继承。
       经典类 和 新式类 区别主要体现在 多继承 上。
"""
--------- 多继承 -----------
Jon 一出生就有 2000 money
Jon is making friends with Maria

--------- women -----------
alex is born a baby...

--------- men -----------
lex 一出生就有 20 money
lex is whoring...
man is sleeping...
lex is talking...
lex is eating...
man is eating...

--------- men 继承 -----------
clark 一出生就有 100 money

--------- women 继承 -----------

Process finished with exit code 0

静态方法

@staticmethod 静态方法 跟 类 的关系切断了,变成了普通的函数
唯一与类的关联就是,如果要调用,必须通过类名(实例名)调用
普通的 类的方法 需要传入self参数。
(如果非要传self参数,需要再把实例传进去,这就失去静态方法的意义了)
用处:把类变成一个工具包组合。

类方法

@classmethod 类方法只能访问类变量,不能访问实例变量(似乎没怎么用过)
场景:强制使用类属性,实例变量改了没用,比如禁止改国籍。

属性方法

@property 导致方法不可调用
效果:把一个方法变成一个静态属性,不再可以加()调用,不能传参数了
作用:隐藏实现细节,只给用户输出结果。






查看类方法的说明文档

import pandas as pd
df = pd.DataFrame(data)
# 查看DataFrame类在哪个模块里:
>>>df.info()
>>>
...
# 查看info()方法说明文档:
print(pd.DataFrame.info.__doc__)

df 的各种操作

df.sum()  # 按字段求和

你可能感兴趣的:(面向对象)