对象,是编程术语,其广义指的是在内存上一段有意义的区域,称作为一个对象。在C中,具有特定长度的类型,可以称作为对象类型,函数不具有特定长度,所以不是对象类型。
广义:在内存上一段有意义的区域,称作为一个对象。
在C中,具有特定长度的类型,可以称作为对象类型,函数不具有特定长度,所以不是对象类型。
在显式支持面向对象的语言中,“对象”一般是指类在内存中装载的实例,具有相关的成员变量和成员函数(也称为:方法)。 ——百度百科
于是耶和华说:你们这些从C族语言来的人啊,去翻一翻Python吧,你的对象不是别人的对象。。
我们知道,在C语言中,对象是类的实例,它意味着 所有对象必须有属性和方法,
但在 Python 中这一概念的定义是松散的,某些对象既没有属性也没有方法 ,而且不是所有的对象都可以子类化 。
Python有云:万物皆对象
这里的对象偏重于“一切都可以赋值给变量或作为参数传递给函数”。
查了一下,对计算机语言中的 对象 这一说法有第一对象之说:
第一类对象(英语:First-class object)在计算机科学中指可以在执行期创造并作为参数传递给其他函数或存入一个变量的实体。将一个实体变为第一类对象的过程叫做“物件化”(Reification)。
第一类对象不一定是面向对象程序设计所指的物件,而可以指任何程序中的实体。一般第一类对象所特有的特性为:可以被存入变量或其他结构
可以被作为参数传递给其他函数
可以被作为函数的返回值
可以在执行期创造,而无需完全在设计期全部写出
即使没有被系结至某一名称,也可以存在
其实在Python中,下列语句有一个共同点是:
在执行时,它们都在堆中搞到了一个内存,即新建了一个对象,
然后把新建的对象绑定到变量名上。
i = 1 -----新建一个PyIntObject对象,然后绑定到i上
s = "abcde" -----新建一个PyStringObject对象,绑定到s上
def foo(): pass -----新建一个PyFunctionObject对象, 绑定到foo上
class C(object): pass -----新建一个类对象,绑定到C上
instance = C() -----新建一个实例对象,绑定到instance上
l = [1,2] -----新建一个PyListObject对象,绑定到l上
t = (1,2) -----新建一个PyTupleObject对象,绑定到t上
所以,到此为止,可以看到,对象在Python当中,是一个极为宽泛的概念。
或许在有人大谈对象的时候,只是在一个角度来聊变量而已。。
另外一个和之前有较大出入的概念是变量:
这二者结合起来可能会互相辅助理解。
我们知道,在C++中,变量的存在十分依附于变量名,当把一个值赋给一个名字(变量)时,这个值会存储在内存之中,称为变量。在大多数语言中,都把这种行为称为“给变量赋值”或“把值存储在变量中”
但Python不是大多数语言。。它并不是把值存储在变量之中,而是更像把值存储在内存里,把变量(名)当做一个标签一样贴到值的旁边。
还记得之前说的引用计数吗? 一个值被赋给一个变量称为一次引用。
连指针都算不上,因为C中的指针也是一个实打实有内存占用的变量。
因而有的人会说:
Python没有变量,只有名字。。
日后发现错,若我记得,会回来改的。。
所以Python的对象到底有何特性?
python使用对象模型来存储数据。构造任何类型的值都是一个对象。
所有python对象都拥有三个特性:身份、类型、值
>>> value = "abc"
>>> id(value) #身份
39102784L
>>> type(value) #类型
'str'>
>>> value #值
'abc'
>>>
关于身份,可以用id()命令查看,会发现这正体现了Python中变量和内存的关系:
>>> a=1
>>> b=1
>>> c=a
>>> id(a)
504157232
>>> id(b)
504157232
>>> id(c)
504157232 //三个都是1,三个的身份一致。这和我们刚才提到的说法一致。
类型、Null对象(None)、文件、集合/固定集合、函数/方法、模块、类
通过type()函数可以查看对象的类型
>>> type(1)
<type 'int'> #它是一个类型对象
>>> type("123")
<type 'str'> #它是一个类型对象
>>> type([1,2,"3"])
<type 'list'> #它是一个类型对象
>>> type((1,2,"3"))
<type 'tuple'> #它是一个类型对象
>>>
类型对象的类型是type,它是所有python类型的根和所有python标准类的默认元类
>>> type(type(1))
<type 'type'>
>>> type(type("123"))
<type 'type'>
>>>
注意:所有标准对象均可用于布尔测试,同类型的对象之间可以比较大小。每个对象天生具有布尔True或False值。值为零的任何数字或者Null对象None的布尔值都是False。
下列对象的布尔值是False:None、False、所有的值为零的数、0(整数)、0.0(浮点数)、0L(长整数)、0.0+0.0j(复数)、“”(空字符串)、[](空列表)、()(空元祖)、{}(空字典)。值不是上面列出来的任何值的对象的布尔值都是True。
不提。。
对象可以被赋值到另一个变量(通过引用)。因为每个变量都指向同一个(共享的)数据对象,只要任何一个引用发生改变,该对象的其他引用也会随之改变。
foo1 = foo2 = 4.3
这个语句的实际意思是一个值为4.3的数字对象被创建(有了内存),然后这个对象的引用被赋值给foo1和foo2,结果就是foo1和foo2指向同一个对象。
foo1 = 4.3
foo2 = foo1
这个例子非常类似上一个,一个值为 4.3 的数值对象被创建,然后赋给一个变量,当执行 foo2 = foo1 时, foo2 被指向 foo1 所指向的同一个对象, 这是因为 Python 通过传递引用来 处理对象。foo2 就成为原始值 4.3 的一个新的引用。这样 foo1 和 foo2 就都指向了同一个对 象。示意图也上图一样。
foo1 = 4.3
foo2 = 1.3 + 3
这个例子有所不同。首先一个数字对象被创建,然后赋值给 foo1. 然后第二个数值对象被 创建并赋值给 foo2. 尽管两个对象保存的是同样大小的值,但事实上系统中保存的都是两个独立的对象,其中foo1是第一个对象的引用, foo2则是第二个对象的引用。如下图给我们这里有两个不同的对象,尽管这两个对象有同样大小的数值。我们为什么在示意图中使用盒子?没错,对象就象一个装着内容的盒子。当一个对象被赋值到一个变量,就象在这个盒子上贴了一个标签,表示创建了一个引用。每当这个对象有了一个新的引用,就会在盒子上新贴一张标签。当一个引用被销毁时,这个标签就会被撕掉。当所有的标签都被撕掉时,这个盒子就会被回收。
那么,Python 是怎么知道这个盒子有多少个标签呢?每个对象都天生具有一个计数器,记录它自己的引用次数。这个数目表示有多少个变量指向该对象。也就是昨天提到的引用计数器。
这样的话,我们昨天所说的内存管理,今天扯了半天的对象概念、变量的内存机制就串起来啦~
Python提供了is和is not运算符来测试两个变量是否指向同一个对象。
>>> a = "123"
>>> id(a)
48523104L
>>> b = "123"
>>> id(b)
48523104L
>>> a is b
True
>>> id(a) == id(b)
True
>>>
所谓可变对象是指,对象的内容可变,而不可变对象是指对象内容不可变
我们可以通过查看id来看一个改变了值的变量是否还是它自己。
>>> aList = ['java',66,88,'python']
>>> aList
['java', 66, 88, 'python']
>>> aList[2]
88
>>> id(aList) #注意观察id值
48255112L
>>> aList[2] = aList[2] + 12
>>> aList[3] = "python2"
>>> aList
['java', 66, 100, 'python2']
>>> id(aList)
48255112L #注意观察id值 两次一样,他还是他。
>>>
下面的例子中,事实上是一个新对象被创建,然后它取代了旧对象。新创建的对象被关联到原来的变量名,旧对象被丢弃,垃圾回收器会在适当的时机回收这些对象。
不信看id啊!
>>> v1 = "python"
>>> id(v1)
31631080L
>>> v1 = "java"
>>> id(v1)
31632240L #由于str是不可变的,重新创建了java对象,随之id改变,旧对象python会在某个时刻被回收
>>>
>>> v2 = 12
>>> v3 = 12
>>> id(v2),id(v3) #同指同一内存区域,id相同
(31489840L, 31489840L)
>>> v2 += 1
>>> v2
13
>>> id(v2),id(v3)
(31489816L, 31489840L)
>>>
1.char或byte
2.指针
3.int vs short vs long
4.float vs double
python的变量时没有类型的。亚更像是名字的标签,想贴哪贴哪。。
资料引用: