类
创建类
-
第一形式
# !/usr/bin/env python
# coding=utf-8
class Person(object): #object表示继承自object类,Python3中可省略次内容
\"\"\"
This is a sample of Class
\"\"\"
breast = 90 #类的属性 是静态变量
def __init__(self, name): #初始化方法 self为对象实例本身
self.name = name
def get_name(self): #类的方法
return self.name
def color(self,color):
d = {}
d[self.name] = color;
return d
if __name__ == \"__main__\":
girl = Person(\"songjia\")
print girl.name
girl.name =\"liu\"
print girl.get_name()
print girl.color(\"white\")
girl.breast = 80 #修改实例的属性
print girl.breast
print Person.breast #类属性不会随实例属性的改变而改变
Person.breast = 100
print Person.breast
print girl.breast
-
第二种形式
>>> __metaclass__ = type
>>> class CC:
... pass
...
>>> cc = CC()
>>> cc.__class__
>>> type(cc)
实例
girl = Person(\"songjia\")
类属性
>>> class A(object): #Python 3: class A:
... x = 7 #类的属性
...
下面列出类的几种特殊属性的含义:
-
C.__name__
:以字符串的形式,返回类的名字,注意这时候得到的仅仅是一个字符串,它不是一个类对象 -
C.__doc__
:显示类的文档 -
C.__base__
:类C的所有父类。如果是按照上面方式定义的类,应该显示object
,因为以上所有类都继承了它。等到学习了“继承”,再来看这个属性,内容就丰富了 -
C.__dict__
:以字典形式显示类的所有属性 -
C.__module__
:类所在的模块
实例属性
>>> class A(object): #Python 3: class A:
... x = 7 #类的属性
...
>>> foo = A()
>>> foo.x #实例属性
类中变量引用可变数据
>>> class B(object):
... y = [1, 2, 3]
>>> B.y #类属性
[1, 2, 3]
>>> bar = B()
>>> bar.y #实例属性
[1, 2, 3]
>>> bar.y.append(4)
>>> bar.y
[1, 2, 3, 4]
>>> B.y
[1, 2, 3, 4]
>>> B.y.append(\"aa\")
>>> B.y
[1, 2, 3, 4, \'aa\']
>>> bar.y
[1, 2, 3, 4, \'aa\']
当类中变量引用的是可变对象是,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。
访问限制
# !/usr/bin/env python
# coding=utf-8
class Person(object):
\"\"\"
This is a sample of Class
\"\"\"
def __init__(self, name): #初始化方法 self为对象实例本身
self.__name = name #__xx双下划线表示类的私有变量
def get_name(self): #类的方法
return self.__name #类的内部可以访问
if __name__ == \"__main__\":
girl = Person(\"songjia\")
print girl.get_name()
print girl._name #无法访问类的私有变量
文档字符串
在函数、类或者文件开头的部分写文档字符串说明,一般采用三重引号。这样写的最大好处是能够用help()函数看。
\"\"\"This is python lesson\"\"\"
def start_func(arg):
\"\"\"This is a function.\"\"\"
pass
class MyClass:
\"\"\"This is my class.\"\"\"
def my_method(self,arg):
\"\"\"This is my method.\"\"\"
pass
继承
单继承
#!/usr/bin/env python
# coding=utf-8
class Person(object): #Python 3: class Person:
def __init__(self, name):
self.name = name
def height(self, m):
h = dict(([\"height\", m],))
return h
def breast(self, n):
b = dict(([\"breast\", n],))
return b
class Girl(Person): #继承
def get_name(self):
return self.name
if __name__ == \"__main__\":
cang = Girl(\"liuguoquan\")
print cang.get_name() #Python 3: print(cang.get_name()),下同,从略
print cang.height(160)
print cang.breast(90)
调用覆盖的方法
class Girl(Person):
def __init__(self, name):
#Person.__init__(self, name) #调用父类的方法
super(Girl, self).__init__(name) #调用父类的方法常用写法
self.real_name = \"Aoi sola\"
def get_name(self):
return self.name
if __name__ == \"__main__\":
cang = Girl(\"canglaoshi\")
print cang.real_name
print cang.get_name()
print cang.height(160)
print cang.breast(90)
执行结果为:
Aoi sola
canglaoshi
{\'height\': 160}
{\'breast\': 90}
多继承
#!/usr/bin/env python
# coding=utf-8
class Person(object): #Python 3: class Person:
def eye(self):
print \"two eyes\"
def breast(self, n):
print \"The breast is: \",n
class Girl(object): #Python 3: class Gril:
age = 28
def color(self):
print \"The girl is white\"
class HotGirl(Person, Girl): #多重继承
pass
if __name__ == \"__main__\":
kong = HotGirl()
kong.eye()
kong.breast(90)
kong.color()
print kong.age
two eyes
The breast is: 90
The girl is white
28
多重继承的顺序-广度优先
class K1(object): #Python 3: class K1:
def foo(self):
print \"K1-foo\" #Python 3: print(\"K1-foo\"),下同,从略
class K2(object): #Python 3: class K2:
def foo(self):
print \"K2-foo\"
def bar(self):
print \"K2-bar\"
class J1(K1, K2):
pass
class J2(K1, K2):
def bar(self):
print \"J2-bar\"
class C(J1, J2):
pass
if __name__ == \"__main__\":
print C.__mro__
m = C()
m.foo()
m.bar()
K1-foo
J2-bar
代码中的print C.__mro__
是要打印出类的继承顺序。从上面清晰看出来了。如果要执行foo()
方法,首先看J1
,没有,看J2
,还没有,看J1
里面的K1
,有了,即C==>J1==>J2==>K1;bar()
也是按照这个顺序,在J2
中就找到了一个。
这种对继承属性和方法搜索的顺序称之为“广度优先”。
Python 2的新式类,以及Python 3中都是按照此顺序原则搜寻属性和方法的。
方法
绑定方法
#!/usr/bin/env python
# coding=utf-8
class Person(object): #Python 3: class Person:
def eye(self):
print \"two eyes\"
def breast(self, n):
print \"The breast is: \",n
class Girl(object): #Python 3: class Gril:
age = 28
def color(self):
print \"The girl is white\"
class HotGirl(Person, Girl): #多重继承
pass
if __name__ == \"__main__\":
kong = HotGirl() #实例化实现了方法和实例的绑
kong.eye() #调用绑定方法
非绑定方法
在子类中,父类的方法就是非绑定方法,因为在子类中,没有建立父类的实例,却要是用父类的方法。
静态方法和类方法
#!/usr/bin/env python
# coding=utf-8
__metaclass__ = type
class StaticMethod: #静态方法
@staticmethod
def foo():
print \"This is static method foo().\"
class ClassMethod: #类方法
@classmethod
def bar(cls): #类方法必须有cls参数
print \"This is class method bar().\"
print \"bar() is part of class:\", cls.__name__
if __name__ == \"__main__\":
static_foo = StaticMethod() #实例化
static_foo.foo() #实例调用静态方法
StaticMethod.foo() #通过类来调用静态方法
print \"********\"
class_bar = ClassMethod()
class_bar.bar()
ClassMethod.bar()
This is static method foo().
This is static method foo().
********
This is class method bar().
bar() is part of class: ClassMethod
This is class method bar().
bar() is part of class: ClassMethod
在python中:
-
@staticmethod
表示下面的方法是静态方法 -
@classmethod
表示下面的方法是类方法
多态和封装
多态
class Cat:
def speak(self):
print \"meow!\"
class Dog:
def speak(self):
print \"woof!\"
class Bob:
def bow(self):
print \"thank you, thank you!\"
def speak(self):
print \"hello, welcome to the neighborhood!\"
def drive(self):
print \"beep, beep!\"
def command(pet):
pet.speak()
pets = [ Cat(), Dog(), Bob() ]
for pet in pets:
command(pet)
Python中的多态特点,Python不检查传入对象的类型,这种方式被称之为“隐式类型”(laten typing)或者“结构式类型”(structural typing),也被通俗的称为“鸭子类型”(duck typeing),Python是弱类型语言。
Java会检查传入对象的类型,所以是强类型语言。
封装和私有化
要了解封装,离不开“私有化”,就是将类或者函数中的某些属性限制在某个区域之内,外部无法调用。
Python中私有化的方法也比较简单,就是在准备私有化的属性(包括方法、数据)名字前面加双下划线。例如:
#!/usr/bin/env python
# coding=utf-8
class ProtectMe(object): #Python 3: class ProtectMe:
def __init__(self):
self.me = \"qiwsir\"
self.__name = \"kivi\" #私有变量
def __python(self): #私有方法
print \"I love Python.\"
def code(self):
print \"Which language do you like?\"
self.__python()
if __name__ == \"__main__\":
p = ProtectMe()
print p.me
print p.code()
如何将一个方法变成属性调用?
可以使用property
函数。
#!/usr/bin/env python
# coding=utf-8
class ProtectMe(object): #Python 3: class ProtectMe:
def __init__(self):
self.me = \"qiwsir\"
self.__name = \"kivi\" #私有变量
def __python(self): #私有方法
print \"I love Python.\"
@property
def code(self):
print \"Which language do you like?\"
self.__python
if __name__ == \"__main__\":
p = ProtectMe()
print p.me
print p.code #调用方法名即可