zoukankan      html  css  js  c++  java
  • python之路——面向对象进阶

    阅读目录

    isinstance和issubclass

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

    class Foo(object):
         pass
    

    obj = Foo()

    isinstance(obj, Foo)

    issubclass(sub, super)检查sub类是否是 super 类的派生类 

    复制代码
    class Foo(object):
        pass
    

    class Bar(Foo):
    pass

    issubclass(Bar, Foo)

    复制代码

    反射

    1 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数

    下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

    def hasattr(*args, **kwargs): # real signature unknown
        """
        Return whether the object has an attribute with the given name.
    
    This is done by calling getattr(obj, name) and catching AttributeError.
    </span><span style="color: #800000;">"""</span>
    <span style="color: #0000ff;">pass</span></pre>
    
    hasattr
    def getattr(object, name, default=None): # known special case of getattr
        """
        getattr(object, name[, default]) -> value
    
    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.
    </span><span style="color: #800000;">"""</span>
    <span style="color: #0000ff;">pass</span></pre>
    
    getattr
    def setattr(x, y, v): # real signature unknown; restored from __doc__
        """
        Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    </span><span style="color: #800000;">"""</span>
    <span style="color: #0000ff;">pass</span></pre>
    
    setattr
    def delattr(x, y): # real signature unknown; restored from __doc__
        """
        Deletes the named attribute from the given object.
    
    delattr(x, 'y') is equivalent to ``del x.y''
    </span><span style="color: #800000;">"""</span>
    <span style="color: #0000ff;">pass</span></pre>
    
    delattr
    class Foo:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
    </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> say_hi(self):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">'</span><span style="color: #800000;">hi,%s</span><span style="color: #800000;">'</span>%<span style="color: #000000;">self.name)
    

    obj=Foo('egon',73)

    #检测是否含有某属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'say_hi'))

    #获取属性
    n=getattr(obj,'name')
    print(n)
    func
    =getattr(obj,'say_hi')
    func()

    print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

    #设置属性
    setattr(obj,'sb',True)
    setattr(obj,
    'show_name',lambda self:self.name+'sb')
    print(obj.dict)
    print(obj.show_name(obj))

    #删除属性
    delattr(obj,'age')
    delattr(obj,
    'show_name')
    delattr(obj,
    'show_name111')#不存在,则报错

    print(obj.dict)

    四个方法的使用演示
    class Foo(object):
    
    staticField </span>= <span style="color: #800000;">"</span><span style="color: #800000;">old boy</span><span style="color: #800000;">"</span>
    
    <span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self):
        self.name </span>= <span style="color: #800000;">'</span><span style="color: #800000;">wupeiqi</span><span style="color: #800000;">'</span>
    
    <span style="color: #0000ff;">def</span><span style="color: #000000;"> func(self):
        </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">func</span><span style="color: #800000;">'</span><span style="color: #000000;">
    
    @staticmethod
    </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> bar():
        </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">bar</span><span style="color: #800000;">'</span>
    

    print getattr(Foo, 'staticField')
    print getattr(Foo, 'func')
    print getattr(Foo, 'bar')

    类也是对象
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    

    import sys

    def s1():
    print 's1'

    def s2():
    print 's2'

    this_module = sys.modules[name]

    hasattr(this_module, 's1')
    getattr(this_module,
    's2')

    反射当前模块成员

    导入其他模块,利用反射查找该模块是否存在某个方法

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

    def test():
    print('from the test')

    View Code
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    

    """
    程序目录:
    module_test.py
    index.py

    当前文件:
    index.py
    """

    import module_test as obj

    #obj.test()

    print(hasattr(obj,'test'))

    getattr(obj,'test')()

    View Code

    __str__和__repr__

    改变对象的字符串显示__str__,__repr__

    自定制格式化字符串__format__

    #_*_coding:utf-8_*_
    
    format_dict={
        'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
        'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
        'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    }
    class School:
        def __init__(self,name,addr,type):
            self.name=name
            self.addr=addr
            self.type=type
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__repr__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">School(%s,%s)</span><span style="color: #800000;">'</span> %<span style="color: #000000;">(self.name,self.addr)
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__str__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">(%s,%s)</span><span style="color: #800000;">'</span> %<span style="color: #000000;">(self.name,self.addr)
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__format__</span><span style="color: #000000;">(self, format_spec):
        </span><span style="color: #008000;">#</span><span style="color: #008000;"> if format_spec</span>
        <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> format_spec <span style="color: #0000ff;">or</span> format_spec <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> format_dict:
            format_spec</span>=<span style="color: #800000;">'</span><span style="color: #800000;">nat</span><span style="color: #800000;">'</span><span style="color: #000000;">
        fmt</span>=<span style="color: #000000;">format_dict[format_spec]
        </span><span style="color: #0000ff;">return</span> fmt.format(obj=<span style="color: #000000;">self)
    

    s1=School('oldboy1','北京','私立')
    print('from repr: ',repr(s1))
    print('from str: ',str(s1))
    print(s1)

    '''
    str函数或者print函数--->obj.str()
    repr或者交互式解释器--->obj.repr()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    '''
    print(format(s1,'nat'))
    print(format(s1,'tna'))
    print(format(s1,'tan'))
    print(format(s1,'asfdasdffd'))

    View Code
    class B:
    
     </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__str__</span><span style="color: #000000;">(self):
         </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">str : class B</span><span style="color: #800000;">'</span>
    
     <span style="color: #0000ff;">def</span> <span style="color: #800080;">__repr__</span><span style="color: #000000;">(self):
         </span><span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">repr : class B</span><span style="color: #800000;">'</span><span style="color: #000000;">
    

    b=B()
    print('%s'%b)
    print('%r'%b)

    %s和%r

    item系列

    __getitem__\__setitem__\__delitem__

    class Foo:
        def __init__(self,name):
            self.name=name
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__getitem__</span><span style="color: #000000;">(self, item):
        </span><span style="color: #0000ff;">print</span>(self.<span style="color: #800080;">__dict__</span><span style="color: #000000;">[item])
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__setitem__</span><span style="color: #000000;">(self, key, value):
        self.</span><span style="color: #800080;">__dict__</span>[key]=<span style="color: #000000;">value
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__delitem__</span><span style="color: #000000;">(self, key):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">'</span><span style="color: #800000;">del obj[key]时,我执行</span><span style="color: #800000;">'</span><span style="color: #000000;">)
        self.</span><span style="color: #800080;">__dict__</span><span style="color: #000000;">.pop(key)
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__delattr__</span><span style="color: #000000;">(self, item):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">'</span><span style="color: #800000;">del obj.key时,我执行</span><span style="color: #800000;">'</span><span style="color: #000000;">)
        self.</span><span style="color: #800080;">__dict__</span><span style="color: #000000;">.pop(item)
    

    f1=Foo('sb')
    f1[
    'age']=18
    f1[
    'age1']=19
    del f1.age1
    del f1['age']
    f1[
    'name']='alex'
    print(f1.dict)

    View Code

    __del__

    析构方法,当对象在内存中被释放时,自动触发执行。

    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    class Foo:
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__del__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">'</span><span style="color: #800000;">执行我啦</span><span style="color: #800000;">'</span><span style="color: #000000;">)
    

    f1=Foo()
    del f1
    print('------->')

    #输出结果
    执行我啦
    ------->

    简单示范

    __new__

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A)
    

    a = A()
    print(a.x)

    View Code
    class Singleton:
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                cls._instance = object.__new__(cls)
            return cls._instance
    

    one = Singleton()
    two
    = Singleton()

    two.a = 3
    print(one.a)
    # 3

    one和two完全相同,可以用id(), ==, is检测

    print(id(one))
    # 29097904
    print(id(two))
    # 29097904
    print(one == two)
    # True
    print(one is two)

    单例模式

    单例模式

    __call__

    对象后面加括号,触发执行。

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    class Foo:
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">pass</span>
    
    <span style="color: #0000ff;">def</span> <span style="color: #800080;">__call__</span>(self, *args, **<span style="color: #000000;">kwargs):
    
        </span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">'</span><span style="color: #800000;">__call__</span><span style="color: #800000;">'</span><span style="color: #000000;">)
    

    obj = Foo() # 执行 init
    obj() # 执行 call

    View Code

    with和__enter__,__exit__

    class A:
        def __enter__(self):
            print('before')
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #ff0000;">'</span><span style="color: #ff0000;">after</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
    

    with A() as a:
    print('123')

    with语句
    class A:
        def __init__(self):
            print('init')
    
    def __enter__(self):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #ff0000;">'</span><span style="color: #ff0000;">before</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        </span><span style="color: #0000ff;">print</span>(<span style="color: #ff0000;">'</span><span style="color: #ff0000;">after</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
    

    with A() as a:
    print('123')

    with语句和init
    class Myfile:
        def __init__(self,path,mode='r',encoding = 'utf-8'):
            self.path = path
            self.mode = mode
            self.encoding = encoding
    
    def __enter__(self):
        self.f </span><span style="color: #808080;">=</span> <span style="color: #0000ff;">open</span>(self.path, mode<span style="color: #808080;">=</span>self.mode, encoding<span style="color: #808080;">=</span><span style="color: #000000;">self.encoding)
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self.f
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.</span><span style="color: #0000ff;">close</span><span style="color: #000000;">()
    

    with Myfile('file',mode='w') as f:
    f.write(
    'wahaha')

    with和文件操作
    import  pickle
    class MyPickledump:
        def __init__(self,path):
            self.path = path
    
    def __enter__(self):
        self.f </span><span style="color: #808080;">=</span> <span style="color: #0000ff;">open</span>(self.path, mode<span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">ab</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self
    
    def </span><span style="color: #0000ff;">dump</span><span style="color: #000000;">(self,content):
        pickle.</span><span style="color: #0000ff;">dump</span><span style="color: #000000;">(content,self.f)
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.</span><span style="color: #0000ff;">close</span><span style="color: #000000;">()
    

    class Mypickleload:
    def init(self,path):
    self.path = path

    def __enter__(self):
        self.f </span><span style="color: #808080;">=</span> <span style="color: #0000ff;">open</span>(self.path, mode<span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">rb</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self
    
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.</span><span style="color: #0000ff;">close</span><span style="color: #000000;">()
    
    def </span><span style="color: #0000ff;">load</span><span style="color: #000000;">(self):
         </span><span style="color: #0000ff;">return</span> pickle.<span style="color: #0000ff;">load</span><span style="color: #000000;">(self.f)
    
    
    def loaditer(self):
        </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
            try:
                yield  self.</span><span style="color: #0000ff;">load</span><span style="color: #000000;">()
            </span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EOFError:
                </span><span style="color: #0000ff;">break</span><span style="color: #000000;">
    

    with MyPickledump('file') as f:

    f.dump({1,2,3,4})

    with Mypickleload('file') as f:
    for item in f.loaditer():
    print(item)

    with和pickle
    import  pickle
    class MyPickledump:
        def __init__(self,path):
            self.path = path
    
    def __enter__(self):
        self.f </span><span style="color: #808080;">=</span> <span style="color: #0000ff;">open</span>(self.path, mode<span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">ab</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self
    
    def </span><span style="color: #0000ff;">dump</span><span style="color: #000000;">(self,content):
        pickle.</span><span style="color: #0000ff;">dump</span><span style="color: #000000;">(content,self.f)
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.</span><span style="color: #0000ff;">close</span><span style="color: #000000;">()
    

    class Mypickleload:
    def init(self,path):
    self.path = path

    def __enter__(self):
        self.f </span><span style="color: #808080;">=</span> <span style="color: #0000ff;">open</span>(self.path, mode<span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">rb</span><span style="color: #ff0000;">'</span><span style="color: #000000;">)
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self
    
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.</span><span style="color: #0000ff;">close</span><span style="color: #000000;">()
    
    def __iter__(self):
        </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
            try:
                yield  pickle.</span><span style="color: #0000ff;">load</span><span style="color: #000000;">(self.f)
            </span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EOFError:
                </span><span style="color: #0000ff;">break</span><span style="color: #000000;">
    

    with MyPickledump('file') as f:

    f.dump({1,2,3,4})

    with Mypickleload('file') as f:
    for item in f:
    print(item)

    with和pickle和iter

    __len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
    <span style="color: #0000ff;">def</span> <span style="color: #800080;">__len__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span> len(self.<span style="color: #800080;">__dict__</span><span style="color: #000000;">)
    

    a = A()
    print(len(a))

    View Code

    __hash__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
    <span style="color: #0000ff;">def</span> <span style="color: #800080;">__hash__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span> hash(str(self.a)+<span style="color: #000000;">str(self.b))
    

    a = A()
    print(hash(a))

    View Code

    __eq__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
    <span style="color: #0000ff;">def</span> <span style="color: #800080;">__eq__</span><span style="color: #000000;">(self,obj):
        </span><span style="color: #0000ff;">if</span>  self.a == obj.a <span style="color: #0000ff;">and</span> self.b ==<span style="color: #000000;"> obj.b:
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> True
    

    a = A()
    b
    = A()
    print(a == b)

    View Code
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self):
        self._cards </span>= [Card(rank,suit) <span style="color: #0000ff;">for</span> rank <span style="color: #0000ff;">in</span><span style="color: #000000;"> FranchDeck.ranks
                                        </span><span style="color: #0000ff;">for</span> suit <span style="color: #0000ff;">in</span><span style="color: #000000;"> FranchDeck.suits]
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__len__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> len(self._cards)
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__getitem__</span><span style="color: #000000;">(self, item):
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self._cards[item]
    

    deck = FranchDeck()
    print(deck[0])
    from random import choice
    print(choice(deck))
    print(choice(deck))

    纸牌游戏
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self):
        self._cards </span>= [Card(rank,suit) <span style="color: #0000ff;">for</span> rank <span style="color: #0000ff;">in</span><span style="color: #000000;"> FranchDeck.ranks
                                        </span><span style="color: #0000ff;">for</span> suit <span style="color: #0000ff;">in</span><span style="color: #000000;"> FranchDeck.suits]
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__len__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> len(self._cards)
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__getitem__</span><span style="color: #000000;">(self, item):
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self._cards[item]
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__setitem__</span><span style="color: #000000;">(self, key, value):
        self._cards[key] </span>=<span style="color: #000000;"> value
    

    deck = FranchDeck()
    print(deck[0])
    from random import choice
    print(choice(deck))
    print(choice(deck))

    from random import shuffle
    shuffle(deck)
    print(deck[:5])

    纸牌游戏2
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__hash__</span><span style="color: #000000;">(self):
        </span><span style="color: #0000ff;">return</span> hash(self.name+<span style="color: #000000;">self.sex)
    
    </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__eq__</span><span style="color: #000000;">(self, other):
        </span><span style="color: #0000ff;">if</span> self.name == other.name <span style="color: #0000ff;">and</span> self.sex == other.sex:<span style="color: #0000ff;">return</span><span style="color: #000000;"> True
    

    p_lst = []
    for i in range(84):
    p_lst.append(Person(
    'egon',i,'male'))

    print(p_lst)
    print(set(p_lst))

    一道面试题
  • 相关阅读:
    flume sink两种类型 file_rool 自定义sing com.mycomm.MySink even if there is only one event, the event has to be sent in an array
    为什么引入进程20年后,又引入线程?
    As of Flume 1.4.0, Avro is the default RPC protocol.
    Google Protocol Buffer 的使用和原理
    Log4j 2
    统一日志 统一订单
    网站行为跟踪 Website Activity Tracking Log Aggregation 日志聚合 In comparison to log-centric systems like Scribe or Flume
    Percolator
    友盟吴磊:移动大数据平台的架构、实践与数据增值
    Twitter的RPC框架Finagle简介
  • 原文地址:https://www.cnblogs.com/l-hf/p/11533705.html
Copyright © 2011-2022 走看看