导航:首页 > 编程语言 > python对象属性和行为最多数量

python对象属性和行为最多数量

发布时间:2023-02-05 12:17:30

A. 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_INIT 1, &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 = 'new string' ,s2的值不会一起改变,因为只是s指向了一个新的对象,s2指向的旧对象的值并没有发生改变
声明 l2 = l ,修改l的值: l.append(6) ,此时l2的值会一起改变,因为l和l2指向的是同一个对象,而该对象的内容被l修改了

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

对于 数值型 对象,Python会默认创建0~2 8 以内的整数对象,也就是 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中采用了内存对象池的技术,是的对象释放的空间会还给内存池,而不是直接释放,后续需要申请空间时,优先从内存对象池中获取。

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

属性的访问机制

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

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

一、__getattr__方法

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

classA:
a=1
def__getattr__(self,item):
print('__getattr__call')
returnitem

t=A()
print(t.a)
print(t.b)
#output
1
__getattr__call
b

二、__getattribute__方法

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

classA:
a=1
def__getattribute__(self,item):
print('__getattribute__call')
raiseAttributeError

def__getattr__(self,item):
print('__getattr__call')
returnitem

t=A()
print(t.a)
print(t.b)

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

def__getattribute__(self,item):
returnobject.__getattribute__(self,item)

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

三、__get__方法

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

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

classDescri(object):
def__get__(self,obj,type=None):
print("callget")

def__set__(self,obj,value):
print("callset")

classA(object):
x=Descri()

a=A()
a.__dict__['x']=1#不会调用__get__
a.x#调用__get__
如果查找的属性是在描述符对象中,则这个描述符会覆盖上文说的属性访问机制,体现在查找链的不同,而这个行文也会因为调用的不同而稍有不一样:

C. 关于Python类和对象的问题

def__area(self):
returnself.a*self.b
def__perimeter(self):
return2*(self.a+self.b)
def__outputarea(self):
print(self.__area())
def__outputperimeter(self):
print(self.__perimeter())

D. python 里的属性是什么意思

楼上的 ,"在python中一切皆对象" 明显不对,谁说在python中一切皆对象

属性,属性方法,方法? 原来的英文贴出来才知道你说的是什么

E. python对象是什么概念

所说所有的变量都是对象。 对象在python里,其实是一个指针,指向一个数据结构,数据结构里有属性,有方法。x0dx0a x0dx0a对象通常就是指变量。从面向对象OO的概念来讲,对象是类的一个实例。在python里很简单,对象就是变量。x0dx0a x0dx0aclass A:x0dx0a myname="class a"x0dx0a上面就是一个类。不是对象x0dx0aa=A()x0dx0a这里变量a就是一个对象。x0dx0a它有一个属性(类属性),myname,你可以显示出来x0dx0aprint a.mynamex0dx0a x0dx0a所以,你看到一个变量后面跟点一个小数点。那么小数点后面就是它的属性或者是方法。带括号的方法。不带就是属性。

F. python 求最大值

####求10个数据的最大值########
list=[]
for i in range(10):#这里可以设置数据的多少
list.append(float(input("请输入数据"))) #输入数据,如果都是整数可以把float改为int
max=list[0]
for i in range(10):#这里数据与上面的for里面的保持一致
if list[i]>max:#如果数据比max大就会更新max
max=list[i]
print("最大值为:%f"%max)#输出
#望采纳

G. 如何理解python的类与对象

1.万物皆对象,把对象归类就有了类;
类也是对象,把类归了类就是超类;
以此类推.
2.对象往往具备(也可以不具备) 行为和属性.
行为我们通常用 函数(function) 实现
属性(attribute)我们通常用 变量 实现
3.因为万物皆对象,所以"函数"&"变量"也是对象
所以 "变量"可以有自己的"函数", "函数"也可以有自己的变量.
4.借此机会练习五笔,所以故意多打了一些字.

H. python中类对象的理解总结

9.3.2. 类对象
类对象支持两种操作:属性引用和实例化。
属性引用 使用和 Python 中所有的属性引用一样的标准语法:obj.name。类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
那么 MyClass.i 和 MyClass.f 是有效的属性引用,分别返回一个整数和一个方法对象。也可以对类属性赋值,你可以通过给 MyClass.i 赋值来修改它。 __doc__ 也是一个有效的属性,返回类的文档字符串:"A simple example class"。
类的 实例化 使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可。例如(假设沿用前面的类):
x = MyClass()
以上创建了一个新的类 实例 并将该对象赋给局部变量 x。
这个实例化操作(“调用”一个类对象)来创建一个空的对象。很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法,像下面这样:
def __init__(self):
self.data = []
类定义了 __init__() 方法的话,类的实例化操作会自动为新创建的类实例调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:
x = MyClass()
当然,出于弹性的需要,__init__() 方法可以有参数。事实上,参数通过 __init__() 传递到类的实例化操作上。例如,
>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

I. 如何理解关于python 面向对象的特性

python中一切皆为对象
其实面向对象没什么高大上的东西,只不过把我们平时对于事物的描述和动作系统的总结成了一个定义事物的方法而已。
我们平时向别人介绍一个他(她)从未见过的东西,会从外形和外貌特征来说明这个东西,比如颜色,大小等,这就对象的属性。还会介绍这个东西能做什么或者有什么用,这就是对象的方法。所以用属性和方法就可以定义一个对象。也就是说一个对象包含了各种属性和方法。
在python中使用对象属性和方法的记法为:object.attribute 或 object.method()
Python中创建对象的第一步是建立一个类(class),这个类就类似于我们区分动物和植物。动物类和植物类各有自己的特征,当我们见到一个事物时,如果它满足动物的特征,我们就说它是动物;如果它满足植物的特征,那么它就属于植物。同样的当我们在python中建立一个类时,就要说名这个类的属性有什么,方法有什么。然后再创建属于这个类的具体实例,也就是对象。那么这个对象也就有了这个类的属性和方法。但具体的属性和方法根据具体对象而定。就像动物类的属性就是有耳朵,有眼睛,有皮毛,方法就是移动,进食等等,具体对象比如说是兔子那就是有长长的耳朵,红色的眼睛,白色的皮毛。方法就是奔跑,进食就是吃胡萝卜。这样理解类和对象或者实例就没什么抽象的了。
__init__(): 创建类的默认属性,也称初始化
__str__() : 返回对象的字符串表达式
多态:对于不同的类可以有同名的方法,同名的方法应用到不同的类可以有不同的行为。
形如:
class Triangle:
def __init__(self, width,height):
self.width = width
self.height = height
def getArea(self):
area = self.width * self.height / 2.0
return area
class Square:
def __init__(self,size):
self.size = size
def getArea(self):
area = self.size * self.size
return area
继承:类可以从其他类继承属性和方法;从其他类继承属性或方法称为派生类或者子类。
形如:class Animal:
def __init__(self,name):
self.name = name
class Dog(Animal):
def __init__(self,color):
self.color = color
def runSpeed():
pass
这样Dog就继承了Animal的name属性。
对象的方法代码暂未想出可以用pass占位。

J. python内存管理机制

由于python中万物皆对象,所以python的存储问题是对象的存储问题。实际上,对于每个对象,python会分配一块内存空间去存储它。
那么python是如何进行内存分配,如何进行内存管理,又是如何释放内存的呢?
总结起来有一下几个方面:引用计数,垃圾回收,内存池机制

python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数

1、对象被创建 a= 'abc'
2、对象被引用 b =a
3、对象被其他的对象引用 li = [1,2,a]
4、对象被作为参数传递给函数:foo(x)

1、变量被删除 del a 或者 del b
2、变量引用了其他对象 b = c 或者 a = c
3、变量离开了所在的作用域(函数调用结束) 比如上面的foo(x)函数结束时,x指向的对象引用减1。
4、在其他的引用对象中被删除(移除) li.remove(a)
5、窗口对象本身被销毁:del li,或者窗口对象本身离开了作用域。

即对象p中的属性引用d,而对象d中属性同时来引用p,从而造成仅仅删除p和d对象,也无法释放其内存空间,因为他们依然在被引用。深入解释就是,循环引用后,p和d被引用个数为2,删除p和d对象后,两者被引用个数变为1,并不是0,而python只有在检查到一个对象的被引用个数为0时,才会自动释放其内存,所以这里无法释放p和d的内存空间

垃圾回收机制: ① 引用计数 , ②标记清除 , ③分带回收

引用计数也是一种垃圾收集机制, 而且也是一种最直观, 最简单的垃圾收集技术.当python某个对象的引用计数降为 0 时, 说明没有任何引用指向该对象, 该对象就成为要被回收的垃圾了.(如果出现循环引用的话, 引用计数机制就不再起作用了)

优点:简单实时性,缺点:维护引用计数消耗资源,且无法解决循环引用。

如果两个对象的引用计数都为 1 , 但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的, 也就是说 它们的引用计数虽然表现为非 0 , 但实际上有效的引用计数为 0 ,.所以先将循环引用摘掉, 就会得出这两个对象的有效计数.

标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

为了提高效率,有很多对象,清理了很多次他依然存在,可以认为,这样的对象不需要经常回收,可以把它分到不同的集合,每个集合回收的时间间隔不同。简单的说这就是python的分代回收。

具体来说,python中的垃圾分为1,2,3代,在1代里的对象每次回收都会去清理,当清理后有引用的对象依然存在,此时他会进入2代集合,同理2代集合清理的时候存在的对象会进入3代集合。

每个集合的清理时间如何分配:会先清理1代垃圾,当清理10次一代垃圾后会清理一次2代垃圾,当清理10次2代垃圾后会清理3代垃圾。

在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,当创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,致使效率降低。
内存池的概念就是预先在内存中申请一定数量的,大小相等的内存块留作备用,当有新的内存需求时,就先从内存池中分配内存给这个需求,不够了之后再申请新的内存。这样做最显着的优势就是能够减少内存碎片,提升效率。

Python中有分为大内存和小内存:(256K为界限分大小内存)
大小小于256kb时,pymalloc会在内存池中申请内存空间,当大于256kb,则会直接执行 new/malloc 的行为来申请新的内存空间

在python中 -5到256之间的数据,系统会默认给每个数字分配一个内存区域,其后有赋值时都会指向固定的已分配的内存区域

在运行py程序的时候,解释器会专门分配一块空白的内存,用来存放纯单词字符组成的字符串(数字,字母,下划线)

字符串赋值时,会先去查找要赋值的字符串是否已存在于内存区域,已存在,则指向已存在的内存,不存在,则会在大整数池中分配一块内存存放此字符串

阅读全文

与python对象属性和行为最多数量相关的资料

热点内容
啄木鸟女星电影 浏览:866
c语言编程源码下载工具 浏览:781
儿女传奇电影系列 浏览:593
武平废品回收小程序源码 浏览:273
工作者迷失1963电影 浏览:703
余美颜摩登情书txt 浏览:819
linux命令大全完整版 浏览:829
单片机画电路图用什么软件好 浏览:108
phpfpm工作原理 浏览:421
加密u盘定制哪家好 浏览:947
如何将视频做成动态表情包安卓 浏览:964
外置打印服务器是什么 浏览:321
加密电脑钱包 浏览:693
javastring编程题 浏览:796
淑女宠爱在线电影 浏览:879
ipadstore是什么app 浏览:485
如何看华为服务器raid的型号 浏览:275
于谦和王宝强一起演的电影 浏览:800
python学习手册epub 浏览:931