类的定义
Python中使用class这个关键词来定义类:
#
# This is an empty class.
#
class AClass:
pass
这里定义了一个空的类,不过这里有一个问题,如果一个类没有定义__init__函数,会报告警,所以之类还是加上:
#
# This is an empty class.
#
class AClass:
def __init__(self):
pass
这样就是一个比较完整的类了。
这里__init__就是一个构造器。
对于上述这样的空类,其实作用不大,仅仅用作命名空间(namespace),可以存放变量之类的:
#
# This is an empty class.
#
class AClass:
def __init__(self):
pass
def Sum(x, y):
print "%d" % (x + y)
if __name__ == "__main__":
a = AClass()
a.x = 0
a.y = 1
a.func = Sum
a.func(a.x, a.y)
上面用到了类的实例化,即a = AClass()。
类的成员
类中可以有静态的数据:
#
# This is a class.
#
class AClass:
Version = 1.0 # Static data.
def __init__(self):
pass
if __name__ == "__main__":
a = AClass()
print a.Version
print AClass.Version
类中还可以有函数,一般不叫函数叫方法:
#
# This is a class.
#
class AClass:
Version = 1.0 # Static data.
def __init__(self):
pass
def printVersion(self):
print self.Version
if __name__ == "__main__":
a = AClass()
a.printVersion()
可以看到__init__其实也算是方法,两者的定义方式一致。
类中的方法需要跟类的实例绑定,它一般有一个参数self,表示实例本身;
调用方法的时候不需要特别指定这个参数。
类中有很多特定的属性:
if __name__ == "__main__":
print dir(AClass)
使用dir来查看属性,下面是结果:
['Version', '__doc__', '__init__', '__module__', 'printVersion']
打印结果如下:
['Version', '__doc__', '__init__', '__module__', 'printVersion']
1.0
None
<unbound method AClass.__init__>
__main__
<unbound method AClass.printVersion>
这里需要注意:
1. __doc__的值是None,是因为没有定义类的说明,可以通过在class定义之后的下一行加入字符串说明:
#
# This is a class.
#
class AClass:
'This is a class'
Version = 1.0 # Static data.
def __init__(self):
pass
def printVersion(self):
print self.Version
2. 后面的unbound的原因是因为没有绑定实例,修改后:
if __name__ == "__main__":
a = AClass()
print dir(AClass)
print a.Version
print a.__doc__
print a.__init__
print a.__module__
print a.printVersion
其结果如下:
['Version', '__doc__', '__init__', '__module__', 'printVersion']
1.0
This is a class
<bound method AClass.__init__ of <__main__.AClass instance at 0x00000000056B4D48>>
__main__
<bound method AClass.printVersion of <__main__.AClass instance at 0x00000000056B4D48>>
前面提到方法与实例是绑定的,也存在两种方法虽然定义在类中,但是不需要与类绑定,它们是静态方法和类方法:
#
# This is a class.
#
class AClass:
'This is a class'
Version = 1.0 # Static data.
def __init__(self):
pass
def printVersion(self):
print self.Version
@staticmethod
def printVersionSts():
print "%d" % AClass.Version
@classmethod
def printVersionCls(cls):
print "%d" % cls.Version
if __name__ == "__main__":
print AClass.printVersionSts
print AClass.printVersionCls
AClass.printVersionSts()
AClass.printVersionCls()
得到的结果如下:
<function printVersionSts at 0x0000000004D52128>
<bound method classobj.printVersionCls of <class __main__.AClass at 0x00000000047F9828>>
1
1
静态方法和类方法通过@staticmethod和@classmethod来修饰。
可以看到它们是直接的绑定的。
类成员一般会区分Public,Private等的,默认Python只有Public类,但是可以通过一些方法类指定Private的类。
在成员名前加双下划线来实现:
#
# This is a class.
#
class AClass:
'This is a class'
Version = 1.0 # Static data.
def __init__(self):
pass
def __printVersion(self):
print self.Version
if __name__ == "__main__":
a = AClass()
a.__printVersion()
这个时候PyLint会报错:
PyLint: Access to a protected member __printVersion of a client class
执行的时候会报错:
Traceback (most recent call last):
File "D:\Code\python_tool_code\LearningPython\Class.py", line 20, in <module>
a.__printVersion()
AttributeError: AClass instance has no attribute '__printVersion'
类的继承
Python中继承直接使用圆括号():
#
# Define a father class.
#
class Father:
#
# __init__ should be defined.
#
def __init__(self, name):
self.name = name
def introduceYourself(self):
print "This is %s." % self.name
#
# Inheritance from Father.
#
class Children(Father): # Use "()" for interitance.
pass
这里就定义了一个继承类Children。
下面是一些使用代码:
#
# Inheritance from Father.
#
class Children(Father): # Use "()" for interitance.
def introduceYourself(self):
Father.introduceYourself(self)
print "This is drived from Father."
if __name__ == "__main__":
p = Father("father")
print Father.__bases__
p.introduceYourself()
s = Children("son")
print Children.__bases__
s.introduceYourself()
下面是运行的结果:
()
This is father.
(<class __main__.Father at 0x0000000004D38BE8>,)
This is son.
This is drived from Father.
需要说明的是:
1. 这里Father没有指定从哪里继承,实际默认就是从object继承;不过手动指定之后:
class Father(object):
得到的结果如下:
(<type 'object'>,)
2. Children从Father继承了所以可以看到__bases__有打印;
3. 子类可以Override父类的方法;
4. 子类会自动调用父类的__init__方法,除非子类Override了父类的__init__方法,此时就需要在子类的__init__里面指定调用父类的__init__(除非不需要);
Python支持多重继承,这里先不讲。