当前位置:首页 » 编程语言 » python对象参数

python对象参数

发布时间: 2025-05-10 03:43:11

python库介绍(一)——inspect

本文旨在深入探讨Python中的inspect库,该库提供了一系列实用功能,用于获取活动对象的信息,包括模块、类、方法、函数、报错追踪、帧对象和代码对象。让我们先从官方文档入手,了解inspect库的基本功能和用途。


官方文档介绍,inspect库提供了多种功能,如检查类的内容、检索方法的源代码、提取并格式化函数的参数列表、展示详细的traceback信息等。下面将重点介绍inspect库的主要方法和属性,以及相关对象的特性。


主要方法和属性

  • inspect.getmembers(object[,predicate]): 返回由object成员(name, value)构成的排序列表,根据name排序。若提供predicate参数,仅返回满足条件的成员。

  • inspect.getmolename(path): 通过输入路径返回模块名称。输入路径为package时返回None。

  • inspect.ismole(object): 判断object是否为mole,返回True或False。

  • inspect.isclass(object): 判断object是否为class,返回True或False。

  • inspect.ismethod(object): 判断object是否为方法,返回True或False。


此外,inspect库还包含一系列以“is”开头的方法和一系列以“get”开头的方法,具体细节可参考官方文档。


Signature对象

Signature对象代表可调用对象的调用签名和返回注解。使用signature()函数创建Signature对象。可调用对象(如函数和方法)可以通过内置函数callable()判断。


下面展示了Signature对象的属性和方法:



  • parameters: 返回有序字典,包含参数名和Parameter对象。

  • return_annotation: 可调用对象的返回注解,无注解时返回Signature.empty。

  • bind(*args, **kwargs): 根据参数构建BoundArguments实例。


Parameter对象

Parameter对象包含函数参数的信息,如参数名、默认值、注解等。Parameter对象不可修改,使用Parameter.replace()方法创建修改后的副本。



  • empty: 无默认值时的Parameter实例。

  • name: 参数名。

  • default: 参数默认值。

  • annotation: 参数注解。

  • kind: 参数种类,以Parameter枚举值表示。


BoundArguments对象

BoundArguments对象用于表示函数调用时参数的绑定情况。与parameters和arguments不同,BoundArguments包含显式绑定的参数。



  • arguments: 参数名到参数值的可变映射,随值变化动态更新。

  • args: 位置参数值的元组。

  • kwargs: 关键字参数值的字典。

  • signature: 与函数关联的Signature对象。

  • apply_defaults(): 设置默认参数。


本文旨在提供对Python inspect库的深入理解,包括其功能、方法、属性及对象的使用。对于需要深入探索inspect库的读者,强烈建议查阅官方文档以获取更详细的指导。本文旨在提供一个概览,帮助读者在实际项目中有效利用inspect库。

❷ python一个对象的属性可以有多少

导读:很多朋友问到关于python一个对象的属性可以有多少的相关问题,本文首席CTO笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!

Python查看对象属性的几种方式:__dict__,dir(),vars(),locals()

为了方便用户查看类中包含哪些属性,Python类提供了__dict__属性。需要注意的一点是,该属性可以用类名或者类的实例对象来调用,用类名直接调用__dict__,会输出该由类中所有类属性组成的字典;而使用类的实例对象调用__dict__,会输出由类中所有实例属性组成的字典。

先来看一下Python类的__dict__属性和类实例对象的__dict__属性,例子如下:

从以上的测试结果中可以得出以下结论:

看几个小例子:

如果没传入参数,就打印当前调用位置的属性和属性值,类似于下面的locals()。

locals()返回调用者当前局部名称空间的字典。在一个函数内部,局部名称空间代表在函数执行时候定义的所有名字,locals()函数返回的就是包含这些名称的字典。

Python对象

众所周知,Python是一门面向对象的语言,在Python无论是数值、字符串、函数亦或是类型、类,都是对象。

对象是在堆上分配的结构,我们定义的所有变量、函数等,都存储于堆内存,而变量名、函数名则是一个存储于栈中、指向堆中具体结构的引用。

要想深入学习Python,首先需要知道Python对象的定义。

我们通常说的Python都是指CPython,底层由C语言实现,源码地址:cpython[GitHub]

Python对象的定义位于Include/object.h,是一个名为PyObject的结构体:

Python中的所有对象都继承自PyObejct,PyObject包含一个用于垃圾回收的双向链表,一个引用计数变量ob_refcnt和一个类型对象指针ob_type

从PyObejct的注释中,我们可以看到这样一句:每个指向可变大小Python对象的指针也可以转换为PyVarObject*(可变大小的Python对象会在下文中解释)。PyVarObejct就是在PyObject的基础上多了一个ob_size字段,用于存储元素个数:

在PyObject结构中,还有一个类型对象指针ob_type,用于表示Python对象是什么类型,定义Python对象类型的是一个PyTypeObject接口体

实际定义是位于Include/cpython/object.h的_typeobject:

在这个类型对象中,不仅包含了对象的类型,还包含了如分配内存大小、对象标准操作等信息,主要分为:

以Python中的int类型为例,int类型对象的定义如下:

从PyObject的定义中我们知道,每个对象的ob_type都要指向一个具体的类型对象,比如一个数值型对象100,它的ob_type会指向int类型对象PyLong_Type。

PyTypeObject结构体第一行是一个PyObject_VAR_HEAD宏,查看宏定义可知PyTypeObject是一个变长对象

也就是说,归根结底类型对象也是一个对象,也有ob_type属性,那PyLong_Type的ob_type是什么呢?

回到PyLong_Type的定义,第一行PyVarObject_HEAD_INIT(PyType_Type,0),查看对应的宏定义

由以上关系可以知道,PyVarObject_HEAD_INIT(PyType_Type,0)={{_PyObject_EXTRA_INIT1,PyType_Type}0},将其代入PyObject_VAR_HEAD,得到一个变长对象:

这样看就很明确了,PyLong_Type的类型就是PyType_Typ,同理可知,Python类型对象的类型就是PyType_Type,而PyType_Type对象的类型是它本身

从上述内容中,我们知道了对象和对象类型的定义,那么根据定义,对象可以有以下两种分类

Python对象定义有PyObject和PyVarObject,因此,根据对象大小是否可变的区别,Python对象可以划分为可变对象(变长对象)和不可变对象(定长对象)

原本的对象a大小并没有改变,只是s引用的对象改变了。这里的对象a、对象b就是定长对象

可以看到,变量l仍然指向对象a,只是对象a的内容发生了改变,数据量变大了。这里的对象a就是变长对象

由于存在以上特性,所以使用这两种对象还会带来一种区别:

声明s2=s,修改s的值:s='newstring',s2的值不会一起改变,因为只是s指向了一个新的对象,s2指向的旧对象的值并没有发生改变

声明l2=l,修改l的值:l.append(6),此时l2的值会一起改变,因为l和l2指向的是同一个对象,而该对象的内容被l修改了

此外,对于字符串对象,Python还有一套内存复用机制,如果两个字符串变量值相同,那它们将共用同一个对象:

对于数值型对象,Python会默认创建0~28以内的整数对象,也就是0~256之间的数值对象是共用的:

按照Python数据类型,对象可分为以下几类:

Python创建对象有两种方式,泛型API和和类型相关的API

这类API通常以PyObject_xxx的形式命名,可以应用在任意Python对象上,如:

使用PyObjecg_New创建一个数值型对象:

这类API通常只能作用于一种类型的对象上,如:

使用PyLong_FromLong创建一个数值型对象:

在我们使用Python声明变量的时候,并不需要为变量指派类型,在给变量赋值的时候,可以赋值任意类型数据,如:

从Python对象的定义我们已经可以知晓造成这个特点的原因了,Python创建对象时,会分配内存进行初始化,然后Python内部通过PyObject*变量来维护这个对象,所以在Python内部各函数直接传递的都是一种泛型指针PyObject*,这个指针所指向的对象类型是不固定的,只能通过所指对象的ob_type属性动态进行判断,而Python正是通过ob_type实现了多态机制

Python在管理维护对象时,通过引用计数来判断内存中的对象是否需要被销毁,Python中所有事物都是对象,所有对象都有引用计数ob_refcnt。

当一个对象的引用计数减少到0之后,Python将会释放该对象所占用的内存和系统资源。

但这并不意味着最终一定会释放内存空间,因为频繁申请释放内存会大大降低Python的执行效率,因此Python中采用了内存对象池的技术,是的对象释放的空间会还给内存池,而不是直接释放,后续需要申请空间时,优先从内存对象池中获取。

python类中的方法属性分别什么意思

很抽象没办法回答

属性:就是类对象的属性,存储某个值这个值的代号可以称为类的属性

方法:把每一项类中所有的功能封装起来称为方法,一般方法里的内容就是方法的执行过程。

举例:比如类表示的是People也就是人

?????人的类中会有一些属性这些属性大概是身高、体重、姓名等等

?????那么方法比如是跑、吃、等等

?

Class?People():

????def?__init__(self,?name):

????????self.name?=?name

????????self.height?=?0

????

????#?比如说跑了一次之后?身高就增长了1个单位

????def?run():

????????print?"开始奔跑"

????????self.height?+=?1

????????print?"奔跑结束"

上面的例子run就是方法;name和height就是属性

run的方法执行过程就是跑完之后height就加1

不知道这样讲你能明白吗

python类的属性有哪几种?如何访问它们?

属性的访问机制

一般情况下,属性访问的默认行为是从对象的字典中获取,并当获取不到时会沿着一定的查找链进行查找。例如?a.x?的查找链就是,从?a.__dict__['x']?,然后是?type(a).__dict__['x']?,再通过?type(a)?的基类开始查找。

若查找链都获取不到属性,则抛出?AttributeError?异常。

一、__getattr__?方法

这个方法是当对象的属性不存在是调用。如果通过正常的机制能找到对象属性的话,不会调用?__getattr__?方法。

class?A:

a?=?1

def?__getattr__(self,?item):

print('__getattr__?call')

return?item

t?=?A()

print(t.a)

print(t.b)

#?output

1

__getattr__?call

b

二、__getattribute__?方法

这个方法会被无条件调用。不管属性存不存在。如果类中还定义了?__getattr__?,则不会调用?__getattr__()方法,除非在?__getattribute__?方法中显示调用__getattr__()?或者抛出了?AttributeError?。

class?A:

a?=?1

def?__getattribute__(self,?item):

print('__getattribute__?call')

raise?AttributeError

def?__getattr__(self,?item):

print('__getattr__?call')

return?item

t?=?A()

print(t.a)

print(t.b)

所以一般情况下,为了保留?__getattr__?的作用,__getattribute__()?方法中一般返回父类的同名方法:

def?__getattribute__(self,?item):

return?object.__getattribute__(self,?item)

使用基类的方法来获取属性能避免在方法中出现无限递归的情况。

三、__get__?方法

这个方法比较简单说明,它与前面的关系不大。

如果一个类中定义了?__get__(),?__set__()?或?__delete__()?中的任何方法。则这个类的对象称为描述符。

class?Descri(object):

def?__get__(self,?obj,?type=None):

print("call?get")

def?__set__(self,?obj,?value):

print("call?set")

class?A(object):

x?=?Descri()

a?=?A()

a.__dict__['x']?=?1??#?不会调用?__get__

a.x??????????????????#?调用?__get__

如果查找的属性是在描述符对象中,则这个描述符会覆盖上文说的属性访问机制,体现在查找链的不同,而这个行文也会因为调用的不同而稍有不一样:

如果调用是对象实例(题目中的调用方式),a.x?则转换为调用:。type(a).__dict__['x'].__get__(a,type(a))

如果调用的是类属性,?A.x?则转换为:A.__dict__['x'].__get__(None,A)

其他情况见文末参考资料的文档

四、__getitem__?方法

这个调用也属于无条件调用,这点与?__getattribute__?一致。区别在于?__getitem__?让类实例允许?[]?运算,可以这样理解:

__getattribute__适用于所有.运算符;

__getitem__适用于所有?[]?运算符。

class?A(object):

????a?=?1

????def?__getitem__(self,?item):

????????print('__getitem__?call')

????????return?item

t?=?A()

print(t['a'])

print(t['b'])

如果仅仅想要对象能够通过?[]?获取对象属性可以简单的:

def?__getitem(self,?item):

????return?object.__getattribute__(self,?item)

总结

当这几个方法同时出现可能就会扰乱你了。我在网上看到一份示例还不错,稍微改了下:

class?C(object):

????a?=?'abc'

????def?__getattribute__(self,?*args,?**kwargs):

????????print("__getattribute__()?is?called")

????????return?object.__getattribute__(self,?*args,?**kwargs)

????#????????return?"haha"

????def?__getattr__(self,?name):

????????print("__getattr__()?is?called?")

????????return?name?+?"?from?getattr"

????def?__get__(self,?instance,?owner):

????????print("__get__()?is?called",?instance,?owner)

????????return?self

????def?__getitem__(self,?item):

????????print('__getitem__?call')

????????return?object.__getattribute__(self,?item)

????def?foo(self,?x):

????????print(x)

class?C2(object):

????d?=?C()

if?__name__?==?'__main__':

????c?=?C()

????c2?=?C2()

????print(c.a)

????print(c.zzzzzzzz)

????c2.d

????print(c2.d.a)

????print(c['a'])

可以结合输出慢慢理解,这里还没涉及继承关系呢。总之,每个以?__get?为前缀的方法都是获取对象内部数据的钩子,名称不一样,用途也存在较大的差异,只有在实践中理解它们,才能真正掌握它们的用法。

结语:以上就是首席CTO笔记为大家整理的关于python一个对象的属性可以有多少的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于python一个对象的属性可以有多少的相关内容别忘了在本站进行查找喔。

热点内容
安卓和苹果平板如何用一个账号 发布:2025-05-10 08:06:02 浏览:184
java学完 发布:2025-05-10 07:49:35 浏览:457
蟹怎么存储 发布:2025-05-10 07:45:14 浏览:534
天谕文件夹 发布:2025-05-10 07:39:31 浏览:652
数据处理算法 发布:2025-05-10 07:35:00 浏览:883
遍历ftp的目录 发布:2025-05-10 07:35:00 浏览:667
数据库宿舍管理系统 发布:2025-05-10 07:24:23 浏览:869
c语言遍历二维数组 发布:2025-05-10 07:17:49 浏览:623
sql合并两列 发布:2025-05-10 07:07:01 浏览:822
linuxmysqlsql 发布:2025-05-10 07:06:12 浏览:918