zoukankan      html  css  js  c++  java
  • 面向对象双下划线方法

    1|0阅读目录


    2|0isinstance和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)

    复制代码
    复制代码

    3|0反射


    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')

    反射当前模块成员

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

    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

    4|0__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

    5|0item系列


    __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

    6|0__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('------->')

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

    简单示范

    7|0__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)

    单例模式

    单例模式

    8|0__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

    9|0with和__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

    10|0__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

    11|0__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

    12|0__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))

    一道面试题
  • 相关阅读:
    vue组件上绑定原生事件
    vue中sync的使用原来这么简单
    vscode快捷键
    justify-content: space-between能够对齐的解决办法
    day_01:__all__、__init__、推导式
    单元测试框架pytest
    ELK从入门到实战
    HTB::Return
    Codeforces Round #752 (Div. 2) ABCD
    动态神经网络综述阅读笔记
  • 原文地址:https://www.cnblogs.com/huanghongzheng/p/11296254.html
Copyright © 2011-2022 走看看