python学习笔记-Day8 上(pickle补充、字段、面向对象成员、成员修饰符、特殊方法)

pickle 序列化补充

# pickle load
# 现在有两个python程序,调用关系如下

# s1.py
class foo:
   ….
Obj = foo(x,y)
Pickle.dump(obj, open(‘db’,’wb’))
S2.py

# s2.py
from s1 import foo

pickle.load(db)

# s2.py 反序列化加载包含对象,一定要先导入对象对应的类,否则Pickle load将会报错

类多继承关系

有共同父类的继承关系如下

如图,如果我们有两个继承(或多个继承)

假设我们要去调用一个方法:

① F类会从左至右去父类寻找,找到D类

② D类没有此方法,继续在D类的父类找,找到B类

③ B类同样没有此方法,这时,python并不会直接去多继承共同父类A中找,而是返回到E类查找,E类同样没有此方法,继续在E类的父类C类查找

④ C类同样没有此方法,这时python回去判断你F类还有没有剩下的继承类,

⑤ 现在没有,则进入到共同的父类A类查找

无共同父类

无共同父类情况,请参考有共同父类

面向对象:多态

# 因为python本身具有多态性,
# 所以这里使用python语法介绍java多态表现形式

class int:
    pass

class float(int): # 继承了int类
    pass

class str(int): # 继承了int类
    pass

# 我创建了三个类,这时我定义一个函数
def func(int arg):  # java必须指定传入参数的类型
    print(arg)

# 这时多态表现是,
obj1 = float()
func(obj1)
obj2 = str()
func(obj2)
obj = int()
func(obj)

# arg参数接收的是int类或int类型的子类,这就是多态

面向对象的成员:字段、方法、属性

类:字段

# 静态字段:country   保存在类中
# 动态字段:self.name  保存在调用的对象中

class Province:
    country = '中国'
    def __init__(self,name):
        self.name = name

hn = Province('河南')
hb = Province('河北')
sd = Province('山东')
db = Province('黑龙江')


# 一般情况下:自己访问自己的字段
# 规则:
#   动态字段只能用对象访问
#   静态字段用类访问(最好不要用对象访问)
hn = Province('河南')
print(hn.name)      # 对象访问动态字段
print(Province.country) # 类访问静态字段
print(hn.country) # 对象访问静态字段(不建议)        

python类中的方法

# Python类中三种方法
#   1. 普通方法: 至少一个self, 对象执行
#   2. 静态方法: 任意参数       类执行(可对象执行,不建议)
#   3. 类方法:   至少一个cls,   类执行(可对象执行,不建议)
class Province:
    country = '中国'
    def __init__(self,name):
        self.name = name
    # 普通方法,由对象去调用执行(方法属于类)
    def show(self):
        print(self.name)

    # 静态方法,由类去调用执行(当方法内部不需要对象中封装的值,可以将方法携程静态方法)
    @staticmethod
    def f1():
        print('test')
    
    # 类方法
    @classmethod
    def f2(cls):
        # cls  # 类名
        # cls()  # 对象
        print(cls)

# 使用类调用的静态方法
Province.f1()

# 使用对象调用普通类方法
obj = Province('111111')
obj.show()

属性

# 属性使用的第一种方式
class Pager:

    def __init__(self, all_count):
        self.all_count = all_count

    @property
    def all_pager(self):
        return self.all_count

    @all_pager.setter
    def all_pager(self,value):
        self.all_count = value

    @all_pager.deleter
    def all_pager(self):
        del self.all_count

# 属性中的修改和删除
# 上边是将方法字段化,但是字段是可以被修改的,

p = Pager(110)
p.all_pager = 123     # 当我去修改它的时候,会执行@all_pager.setter装饰器下的函数进行修改(本身装饰器指引作用,并不会有帮你去实现修改功能)

print(p.all_pager)  # 现在已经被修改

del p.all_pager  # 同样,del会找到类 @all_pager.deleter装饰器下的all_pager方法,同样也不会实现删除功能
# p.all_pager  # 因为已经被删除,这样调用时会报错的
# 属性存在的第二种方式
class Pager:

    def __init__(self, all_count):
        self.all_count = all_count

    def f1(self):
        return self.all_count

    def f2(self,value):
        self.all_count = value

    def f3(self):
        del self.all_count

    foo = property(fget=f1, fset=f2, fdel=f3)

p = Pager(101)

result = p.foo   # 调用fget
print(result)

p.foo = 123   # 设置 fset
print(p.foo)

del p.foo      # 删除 fdel

成员修饰符

# 成员修饰符
# 私有:
#    只有类自己本身(私有动态字段、静态字段, 私有静态方法、普通方法、类方法,  私有的属性)
# 公有:
#    可在类外访问,可在对象访问的都是公有
# PS: 不到万不得已,不要在外部强制访问私有成员  _类名__私有xxx

class Foo:
    __cc = 'test'    # 私有的静态字段
    def __init__(self,name):
        self.__name = name   # 私有动态字段

    @staticmethod
    def __f1():  # 私有的静态方法
        return '私有静态'

    def __f2(self):  #私有的普通方法
        return '私有普通方法'

    @classmethod
    def __f3(cls):  # 私有的类方法
        return cls, '私有类方法'

    @property
    def __f4(self):
        return '私有属性'

    def f10(self):
        print(Foo.__f1())   # 调用私有静态方法
        print(self.__f2())  # 调用私有普通方法
        print(Foo.__f3())   # 调用私有的类方法
        print(self.__f4)  # 调用私有属性

obj = Foo('eason')
obj.f10()

特殊方法、构造方法、析构方法

# 构造方法、析构方法、特殊方法

class Foo:

    # 构造方法,当对象被调用(例Foo() )
    def __init__(self,name,age):
        self.name = name
        self.age = age

    # 析构方法,在内存垃圾回收之前,执行的方法
    def __del__(self):
        pass

    # 特殊方法
    # call , 对象被调用时执行的方法
    def __call__(self):
        print('call')

    # str, 更改默认对象返回值
    def __str__(self):
        return  '%s - %d' % (self.name, self.age)

obj = Foo('jack',18)   # 构造方法执行
obj()         # call方法
Foo('eason',24)()       # 类调用call方法

obj1 = Foo('alex',55)

print(obj1)  # 默认没有__str__方法,将返回内存地址,有__str__方法执行__str__方法

# 获取对象中封装的数据
ret = obj1.__dict__
print(ret)

 

posted @ 2016-07-01 22:48  Cool_King  阅读(253)  评论(0编辑  收藏  举报