java中的类与python类有点不同。python有类对象class object和实例对象(instance object)的概念。
Class Objects Provide Default Behavior(来自learning python)
When we run a class statement, we get a class object. Here’s a rundown of the main
properties of Python classes:当我们运行class语句时,就得到了一个类对象)
• The class statement creates a class object and assigns it a name. Just like the
function def statement, the Python class statement is an executable statement.
When reached and run, it generates a new class object, and assigns it to the
name in the class header. Also, like defs, class statements typically run when the
files they are coded in are first imported.(python class语句时自执行的语句,当执行完成后,产生了
一个class object,类对象名字为类的名字)
• Assignments inside class statements make class attributes. Just like in module
files, top-level assignments within a class statement (not nested in a def) generate
attributes in a class object. Technically, the class statement scope morphs
into the attribute namespace of the class object, just like a module’s global
scope. After running a class statement, class attributes are accessed by name
qualification: object.name.
• Class attributes provide object state and behavior. Attributes of a class object
record state information and behavior to be shared by all instances created from
the class; function def statements nested inside a class generate methods, which
process instances.
class语句内的赋值语句会创建类的属性。
就像模块文件一样,class语句内的顶层的赋值语句(不是在def之内)会产生类对象中的属性。类的属性可由变量名点号运算获取object.name.
def MyClass:
i=1234
MyClass.i
在方法内对self属性做赋值运算会产生每个实例自己的属性。self同java中的this,代表当前正在处理的对象,而不是class
在类方法函数内,第一个参数(按惯例称为self)会引用正处理的实例对象。
Assignments to attributes of self in methods make per-instance attributes.
Inside class method functions, the first argument (called self by convention) references
the instance object being processed; assignments to attributes of self
create or change data in the instance, not the class.
class FirstClass:
def setdata(self,value):
self.data=value
def display(self):
print self.data
>>> x=FirstClass()
>>> x.setdata(123)
>>> x.display()
123
>>> x.data=5
>>> x.display()
5
另一种喜欢这个模型的动态性的方式是,考虑一下我们可以在类的内部或外部修改实例属性,在类内,通过方法内对self进行赋值运算,而在类外时,则可以通过对实例对象进行赋值运算,如上面的:
x.data=5
虽然比较少见,通过在类方法函数外对变量名进行赋值运算,我们甚至可以在实例命名空间内产生全新的属性
x.anothername='spam'
类对象支持两种操作:属性引用和实例化。
属性引用使用和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
”。
(我们调用MyClass.f 输出:<unbound method MyClass.func>
调用MyClass.f()输出:TypeError: unbound method func() must be called with MyClass instance as first argument (got nothing instead)
调用MyClass.f(x)正常输出。
类的实例化使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可。例如(假设沿用前面的类) :
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)
实例对象
现在我们可以用实例对象作什么?实例对象唯一可用的操作就是属性引用。有两种有效的属性名。
第一种称作数据属性。这相当于Smalltalk中的“实例变量”或C++中的“数据成员”。和局部变量一样,数据属性不需要声明,第一次使用时它们就会生成。例如,如果x是前面创建的MyClass实例,下面这段代码会打印出16而不会有任何多余的残留:
x.counter = 1 while x.counter < 10: x.counter = x.counter * 2 print x.counter del x.counter
第二种为实例对象所接受的引用属性是方法。方法是属于一个对象的函数。(在Python中,方法不止是类实例所独有:其它类型的对象也可有方法。例如,链表对象有append,insert,remove,sort等等方法。然而,在这里,除非特别说明,我们提到的方法特指类方法)(ps:
我要提醒读者,这里有一个面向对象方面的术语陷阱,在Python中“对象”这个词不一定指类实例。Python中并非所有的类型都是类:例如整型、链表这些内置数据类型就不是,甚至某些像文件这样的外部类型也不是,这一点类似于C++和Modula-3,而不像Smalltalk。然而,所有的Python类型在语义上都有一点相同之处:描述它们的最贴切词语是“对象”。
对象是被特化的,多个名字(在多个作用域中)可以绑定同一个对象。这相当于其它语言中的别名。通常对Python的第一印象中会忽略这一点,使用那些不可变的基本类型(数值、字符串、元组)时也可以很放心的忽视它。然而,在Python代码调用字典、链表之类可变对象,以及大多数涉及程序外部实体(文件、窗体等等)的类型时,这一语义就会有影响。这通用有助于优化程序,因为别名的行为在某些方面类似于指针。例如,很容易传递一个对象,因为在行为上只是传递了一个指针。如果函数修改了一个通过参数传递的对象,调用者可以接收到变化--在Pascal中这需要两个不同的参数传递机制。
实例对象的有效名称依赖于它的类。按照定义,类中所有(用户定义)的函数对象对应它的实例中的方法。所以在我们的例子中,x..f是一个有效的方法引用,因为MyClass.f是一个函数。但x.i不是,因为MyClass.i是不是函数。不过x.f和MyClass.f不同--它是一个 方法对象,不是一个函数对象。
方法对象
通常方法是直接调用的:
x.f()
在我们的例子中,这会返回字符串‘hello world’。然而,也不是一定要直接调用方法。x.f
是一个方法对象,它可以存储起来以后调用。例如:
xf = x.f while True: print xf()
会不断的打印“Hello world”。
调用方法时发生了什么?你可能注意到调用 x.f()
时没有引用前面标出的变量,尽管在f的函数定义中指明了一个参数。这个参数怎么了?事实上如果函数调用中缺少参数,Python会抛出异常--甚至这个参数实际上没什么用……
实际上,你可能已经猜到了答案:方法的特别之处在于实例对象作为函数的第一个参数传给了函数。在我们的例子中,调用x.f()
相当于MyClass.f(x)。通常,以n个参数的列表去调用一个方法就相当于将方法的对象插入到参数列表的最前面后,以这个列表去调用相应的函数。
如果你还是不理解方法的工作原理,了解一下它的实现也许有帮助。引用非数据属性的实例属性时,会搜索它的类。如果这个命名确认为一个有效的函数对象类属性,就会将实例对象和函数对象封装进一个抽象对象:这就是方法对象。以一个参数列表调用方法对象时,它被重新拆封,用实例对象和原始的参数列表构造一个新的参数列表,然后函数对象调用这个新的参数列表。
参考自:http://sebug.net/paper/books/python_hb/node11.html
python对象
何谓对象?(来自dive into python)
在 Python 中一切都是对象,并且几乎一切都有属性和方法。所有的函数都有一个内置的 __doc__ 属性,它会返回在函数源代码中定义的 doc string;sys 模块是一个对象,它有一个叫作 path的属性;等等。
我们仍然在回避问题的实质,究竟何谓对象?不同的编程语言以不同的方式定义 “对象” 。 某些语言中,它意味着所有 对象必须 有属性和方法;另一些语言中,它意味着所有的对象都可以子类化。在 Python 中,定义是松散的;某些对象既没有属性也没有方法 (关于这一点的说明在 第 3 章),而且不是所有的对象都可以子类化 (关于这一点的说明在第 5 章)。但是万物皆对象从感性上可以解释为:一切都可以赋值给变量或作为参数传递给函数 (关于这一点的说明在第 4 章)。
这一点太重要了,所以我会在刚开始就不止一次地反复强调它,以免您没注意到:在 Python 中万物皆对象。字符串是对象。列表是对象。函数是对象。甚至模块也是对象,这一点我们很快会看到。
进一步阅读
- Python Reference Manual 确切解释了在 Python 中万物皆对象的含义,因为有些书生气十足的人,喜欢花时间讨论这类的问题。
- eff-bot 总结了 Python 对象.
Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in conformance to Von Neumann’s model of a “stored program computer,” code is also represented by objects.)
Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is‘ operator compares the identity of two objects; the id() function returns an integer representing its identity (currently implemented as its address). An object’s type is also unchangeable. [1] An object’s type determines the operations that the object supports (e.g., “does it have a length?”) and also defines the possible values for objects of that type. The type() function returns an object’s type (which is an object itself). The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.
Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable.