day08 面向对象补充及单例模式

一、面向对象中的静态字段和普通字段

静态字段、和普通字段
使用规范:
普通字段只能用对象访问
静态字段用类来访问 (在Python中静态字段可以用对象访问也可以用类访问,但在其他语言中只能用类来访问静态字段,而且为防止在某种情况下报错,在使用静态字段时需用类来访问)
class Province:
    country = 'China'  # 静态字段     静态字段是属于类的       当有无数个对象时,没个对象都有一个同样的字段,这样的话会浪费内存,所以设定一个静态字段,只需在内存里创建一次即可

    def __init__(self, name):
        self.name = name  # 普通字段   普通字段是属于对象的   每创建一个对象,就会在对象所存放的内存里创建一个对象的普通字段

二、静态方法、普通方法、类方法

静态方法
静态方法直接通过类来调用
当方法中不需要通过类中的值时,将方法写为静态方法

普通方法
由对象来调用,普通方法属于类

类方法
class Foo:
    def __init__(self, name):
        self.name = name

    def show(self):
        print(self.name)

    @staticmethod
    def static():
        print("static method")

    @classmethod
    def clsmethod(cls):
        # cls  为类名  那么可以通过cls后面加括号cls()来调用类
        print(cls)


Foo.clsmethod()


# 类只的所有方法:
#    普通方法:至少一个self,通过对象来执行
#    静态方法:可以有任意个参数,通过类来执行(也可通过对象那个来执行,但不到万不得已不要这么做)
#    类方法:  至少一个cls,通过类来执行(也可通过对象那个来执行,但不到万不得已不要这么做)

三、属性

具有方法的代码写作方式,具有字段的访问形式
@property @类名.setter @类名.deleter
class pager:
    def __init__(self, all_count):
        self.all_count = all_count

    @property
    def all_pager(self):  # 调用时可以像普通字段一样取值  格式:对象名.字段名
        a1, a2 = divmod(self.all_count, 10)
        if a2 == 0:
            return a1
        else:
            return a1 + a2

    @all_pager.setter  # 调用时可以像普通字段一样赋值    格式:对象名.字段名 = xxx
    def all_pager(self, value):
        pass

    @all_pager.deleter
    def all_pager(self):  # 调用时可以像普通字段一样删除值    格式:del 对象名.字段名
        pass

#调用
pp = pager
pp_get = pp.all_pager
pp.all_pager = 'xxx'
del pp.all_pager



class class_attr:

#属性的另外一种形式
    def f1(self):
        return 'test'

    def f2(self, value):
        pass

    def f3(self):
        pass

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


#调用:
p = class_attr()
res = p.foo
p.foo = 'xxx'
del p.foo

四、多态

    多态即多种形态,在运行时确定其状态,在编译阶段无法确定其类型,这就是多态。Python中的多态和Java以及C++中的多态有点不同,Python中的变量是弱类型的,在定义时不用指明其类型,它会根据需要在运行时确定变量的类型(个人觉得这也是多态的一种体现),并且Python本身是一种解释性语言,不进行预编译,因此它就只在运行时确定其状态,故也有人说Python是一种多态语言。在Python中很多地方都可以体现多态的特性,比如 内置函数len(object),len函数不仅可以计算字符串的长度,还可以计算列表、元组等对象中的数据个数,这里在运行时通过参数类型确定其具体的计算过程,正是多态的一种体现。有些朋友提出Python不支持多态,我是完全不赞同的.

    Python以它这种独有的方式体现多态的根本原因我觉得有两点:1)Python是解释性语言;2)Python中变量是弱类型的。所以Python体现多态的方式和Java决然不同,但是不能因为同Java中体现多态的方式不同就认为Python不支持多态,这种想法过于片面。

 

来自:    http://blog.csdn.net/chongtianfeiyu/article/details/21894005

面向对象-多态

五、特殊方法

#!/usr/bin/env python
# _*_ conding:utf-8_*_


class Foo:

    #构造方法
    def __init__(self,name):
        self.name = name

    #析构方法    进行垃圾回收时在内存中删除对象时,如果类中定义了析构方法时,执行析构方法中的内容的再删除
    def __del__(self):
        pass

    #call方法    实例名()    实例名后面加括号调用该实例的call方法
    def __call__(self, *args, **kwargs):
        pass

    #str方法   print(实例)时,未定义str方法时输出该实例的类名及在内存的中地址  定义后输出str方法里定义的内容
    def __str__(self):
        pass

    #dict方法   获取对象中封装的数据
print(Foo.__dict__)

#输出    {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__str__': <function Foo.__str__ at 0x0000000001116048>,
# '__del__': <function Foo.__del__ at 0x000000000110BEA0>, '__call__': <function Foo.__call__ at 0x000000000110BF28>,
# '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__init__': <function Foo.__init__ at 0x000000000110BE18>}
obj = Foo('test')
print(obj.__dict__)
#输出  {'name': 'test'}


class foo:

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

    def __getitem__(self, item):
        print("getitem")

    def __setitem__(self, key, value):
        print("setitem")


    def __delitem__(self, key):
        print("del item")

obj = foo('xuanouba')
obj['xuanouba']
#结果  getitem
obj['test'] = 'aa'
print(obj.__dict__)
#结果  setitem
del obj['test']
#结果 del item



#__iter__方法   当将对象放到一个for循环里时,自动执行对象的__iter__方法
class FOO:

    def __iter__(self):
        yield 1
        yield 2

obj = FOO()
for i in obj:
    print(i)

 

六、其他方法

super方法
#super方法

class Foo:

    def f1(self):
        print('Foo')

class Bar(Foo):

    def f1(self):
        #主动执行父类的f1方法
        super(Bar,self).f1()
        print('Bar')

obj = Bar()
obj.f1()

isinstance()方法
# isinstance()
#eg:
isinstance(obj,Foo)
res = isinstance(obj,Bar)    #判断obj实例是不是Bar类型
print(res)
res = isinstance(obj,Foo)    #(Foo是Bar的父类)判断是不是Bar类型的父类的类型
print(res)
issubclass()方法
# issubclass()
#eg:
issubclass(Foo,Bar)    判断Foo类型是不是Bar类型的子类
七、成员修饰符
#!/usr/bin/env python
# _*_ conding:utf-8_*_


#成员修饰符:
#    私有:只有类自己内部能访问,外部不能直接访问,在成员前加__(两个下划线),##也不能继承##
#在外部也可访问私有字段或私有方法,类似obj._Foo__cc  #对象名._类名私有静态字段名 !! 不到万不得已不要用!!

class Foo:

    __cc = 'name'

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

    def f1(self):
        """
        访问私有成员时,只能同过这样的方式,在内部调用,然后外部通过共有方法的方式来间接访问,私有静态字段也一样
        :return:
        """
        print(self.__name)

    def f2(self):
        print(Foo.__cc)


p = Foo('test')
# print(p.__name)   #这样直接访问类的私有成员会报错
# print(Foo.__cc)    #这样直接访问类的私有静态字段也会报错



class FOO:

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

    def __f1(self):
        print("私有f1")

    def f1(self):
        print("共有f1")


obj = FOO('ALEX')
# obj.__f1()    #会报错,因为是私有方法
obj.f1()
 
八、实现有序字典
#!/usr/bin/env python
# _*_ conding:utf-8_*_

#字典虽是无序的,但Python中的列表是有序的,利用这个特性,来实现的自定义的有序字典

class Mydict(dict):     #继承Python提供的dict类

    def __init__(self):
        self.li = []        #创建一个空列表
        super(Mydict,self).__init__()   #执行dict类中的__init__方法

    def __setitem__(self, key, value):
        self.li.append(key)     #往字典中添加新的键值对时将key 追加到列表中
        super(Mydict,self).__setitem__(key,value)

    def __str__(self):
        temp_list = []   #设置一个临时空列表
        for key in self.li:
            value = self.get(key)
            temp_list.append("'{}':{}".format(key,value)) #将每一对键值对以 "'a':1" 这样的方式作为一个字符串追加到临时列表中
        temp_str = '{' + ",".join(temp_list) + '}'    #最后已列表的形式返回给用户
        return temp_str

obj = Mydict()
obj['a'] = 1
obj['b'] = 2
print(obj)
九、单例模式
class Foo:

    instance = None

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

    @classmethod
    def get_instance(cls):      #类方法,通过类直接调用,
        if cls.instance:             #如果现在已经有实例,则将实例直接返回给对象
            return cls.instance
        else:                      #如果现在没有实例,那么创建一个实例,然后返回给对象
            obj = cls('test')
            cls.instance = obj
            return obj
    #    这样的话每次实例化一个对象的时候,都返回的是同一个实例

obj1 = Foo.get_instance()
obj2 = Foo.get_instance()
print(obj1)
print(obj2)

更多关于单例模式:

    http://www.cnblogs.com/seesea125/archive/2012/04/05/2433463.html

 单例模式介绍 单例模式

posted on 2016-06-28 16:39  宣欧巴  阅读(139)  评论(0编辑  收藏  举报