python函数和类的一些研究
admin
2023-07-31 01:45:01
0

bound与unbound

通常认为实例方法是bound的,而类方法是unbound的,这种说法也没错,只是对于不同类型变量来说,结果是不同的

class A(object):
    \"\"\"test class\"\"\"
    _instance = None
    
    def __private(self):
        pass

    def _protect(self):
        pass

    def fs(self):
        pass

    @staticmethod
    def sm():
        pass

    @classmethod
    def fc(cls):
        pass

测试一下, 结果显示的都是bound method

>>> a = A()
>>> a.fs
>
>>> a.fc
>

直接从类访问,结果fs这个实例方法显示的是unbound。可以知道bound的意义并不是始终不变的,对于不同的对象来说意义并不一样。

>>> A.fs

>>> A.fc
>

python里面类方法实例方法可以等价变换

a.fs()
# equals
A.fs(a)

从描述器的角度看

>>> A.__dict__[\'fs\'].__get__(None, A)


>>> A.__dict__[\'fs\'].__get__(a, A)
>

>>> A.__dict__[\'fc\'].__get__(None, A)
>

不过实例a调用静态方法会出错(TypeError),因为实例对方法的调用提供了self参数,但sm是没有参数的。但是这提供了另一种思路)比如在python的多进程编程中,进程跑的函数如果是实例函数的会因为无法序列化而失败,但如果是staticmethod就没有问题,静态函数的本质其实也就是普通函数。
所以可以这样

class B(object):
    @staticmethod
    def run(inst):
        inst.foo()
    
    def foo(self):
        print \'foo\'

b = B()
B.run(b)

在2.x中区分实例函数和类函数可以用im_self

>>> A.fs.im_self
None
>>> A.fc.im_self

至于通过实例引用方法时的im_self的值,大家自己可以探索下

获取类中所有定义的方法

  1. 使用dir函数

>>> dir(A)
[\'_A__private\',
 \'__class__\',
 \'__delattr__\',
 \'__dict__\',
 \'__doc__\',
 \'__format__\',
 \'__getattribute__\',
 \'__hash__\',
 \'__init__\',
 \'__module__\',
 \'__new__\',
 \'__reduce__\',
 \'__reduce_ex__\',
 \'__repr__\',
 \'__setattr__\',
 \'__sizeof__\',
 \'__str__\',
 \'__subclasshook__\',
 \'__weakref__\',
 \'_instance\',
 \'_protect\',
 \'fc\',
 \'fs\',
 \'sm\']

2 使用inspect.getmembers
这个除了函数名的字符串以外,连对象的type也得到了,结果更加详细

>>> inspect.getmembers(A)
[(\'_A__private\', ),
 (\'__class__\', type),
 (\'__delattr__\', ),
 (\'__dict__\',
  ,
   \'__dict__\': ,
   \'__doc__\': \'test class\',
   \'__module__\': \'__main__\',
   \'__weakref__\': ,
   \'_instance\': None,
   \'_protect\': ,
   \'fc\': ,
   \'fs\': ,
   \'sm\': }>),
 (\'__doc__\', \'test class\'),
 (\'__format__\', ),
 (\'__getattribute__\', ),
 (\'__hash__\', ),
 (\'__init__\', ),
 (\'__module__\', \'__main__\'),
 (\'__new__\', ),
 (\'__reduce__\', ),
 (\'__reduce_ex__\', ),
 (\'__repr__\', ),
 (\'__setattr__\', ),
 (\'__sizeof__\', ),
 (\'__str__\', ),
 (\'__subclasshook__\', ),
 (\'__weakref__\', ),
 (\'_instance\', None),
 (\'_protect\', ),
 (\'fc\', >),
 (\'fs\', ),
 (\'sm\', )]

判断某个属性是否可调用

a = A()
callable(getattr(a, \'testattr\', None))

获得一个对象中所有可调用的方法

[method for method in dir(object) if callable(getattr(object, method))]

隐藏属性

重写__dict__或者__dir__

class C(object):
    __dict__ = {}
    
    def __dir__(self):
        return [\'cherry\']

注意,这里的__dict__不是类的,是实例的,类的__dict__是不可写的,不信可以试试
__dir__很奇怪,如果dir函数用在C的实例上,确实会返回[\'cherry\'],但dir(C)还是能得到类中所有属性,有点掩耳盗铃的感觉,待继续研究

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...