python之面向对象编程

面向对象三大特性之封装

class Foo:
def __init__(self,host,port,user,pwd):
self.host = host
self.port = port
self.user = user
self.pwd = pwd
def mysql_select(self):
print self.host
def mysql_delet(self):
pass
def mysql_add(self):
pass
def mysql_update(self):
pass

obj1 = Foo('10.10.0.1','3306','root','123') #把参数封装到Fooself
obj2 = Foo('192.168.1.1','3306','root','456')

obj1.mysql_select()
obj2.mysql_select()


练习二:游戏人生程序

1、创建三个游戏人物,分别是:

  • 苍井井,女,18,初始战斗力1000
  • 王俊,男,20,初始战斗力1800
  • 波多多,女,19,初始战斗力2500

2、游戏场景,分别:

  • 草丛战斗,消耗200战斗力
  • 自我修炼,增长100战斗力
  • 多人游戏,消耗500战斗力
# #####################  定义实现功能的类  #####################
class Person:
    def __init__(self,name,sex,age,power):
        self.name = name
        self.sex = sex
        self.age = age
        self.power =  power
    def grass(self):    #草丛作战
self.power = self.power - 200  #草丛战斗,消耗200战斗力
def study(self):    #自我修炼
self.power = self.power + 100   #自我修炼,增加100战斗力
def people(self):   #多人游戏
self.power = self.power - 500   #参加多人游戏,消耗500战斗力
def detail(self):   #人物详情
temp = '姓名:%s;性别%s;年龄%s;战斗力%s'%(self.name,self.sex,self.age,self.power)
        print temp

# #####################  开始游戏  #####################
cang = Person('苍井井','女',18,1000)    #创建苍井井角色
wj = Person('王俊','男',20,1800)       #创建王俊角色
bo = Person('波多多','女',19,2500)    #创建波多多角色

cang.people()   #苍井井参加了一次多人游戏
wj.grass()      #王俊参加了一次草丛作战
bo.study()      #波多多自我修炼了一次

#输出当前人物详情
cang.detail()
wj.detail()
bo.detail()

cang.grass()   #苍井井参加了一次草丛作战
wj.grass()      #王俊又参加了一次草丛作战
bo.people()     #波多多参加了一次多人游戏

#再次输出当前人物详情
cang.detail()
wj.detail()
bo.detail()

  

 
面向对象三大特性之继承
#!/usr/bin/env python
#codencoding: utf-8
class A:
def a1(self):
print 'a1'
class B(A): #定义B继承A中的方法
def b1(self):
print 'b1'
obj=B() #obj封装到类B
obj.b1()
obj.a1() #继承后,obj才可以调用A中的方法

1、Python的类可以继承多个类,Java和C#中则只能继承一个类

2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先广度优先

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找

经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。

 

 

当类是经典类时,多继承情况下,会按照深度优先方式查找  

 

 

#codencoding: utf-8
class D:
    def bar(self):
        print 'D.bar'
class C(D):
    def bar(self):
        print 'C.bar'
class B(D):
    def bar2(self):
        print 'B.bar'
class A(B, C):
    def bar1(self):
        print 'A.bar'

a = A()

  

# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
# 所以,查找顺序:
A --> B --> D --> C
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()

 

当类是新式类时,多继承情况下,会按照广度优先方式查找

 

#!/usr/bin/env python
#codencoding: utf-8
class D(object):
    def bar(self):
        print 'D.bar'
class C(D):
    def bar(self):
        print 'C.bar'
class B(D):
    def bar2(self):
        print 'B.bar'
class A(B, C):
    def bar1(self):
        print 'A.bar'
a = A()

  

# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
# 所以,查找顺序:
A --> B --> C --> D
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()
 
面向对象类成员之字段
#!/usr/bin/env python
#codencoding: utf-8
class Foo:
def __init__(self,name,age):
self.name = name
self.age = age
def fun1(self):
print 'fun1'
@property #将方法fun2转换为字段
def fun2(self):
print 'fun2'
obj = Foo('yangmv',22)

obj.fun1()
obj.fun2 #func被转换为字段,所以可以直接以字段的形式调用

#!/usr/bin/env python
#codencoding: utf-8
class Foo
:
country =
'中国'               #静态字段。保存在类中
def __init__
(
self,
name):
self
.name = name
#普通字段。保存在对象中
obj_hb = Foo(
'湖北'
)
print 
obj_hb.name
print 
Foo.country
 

由上图可是:

  • 静态字段在内存中只保存一份
  • 普通字段在每个对象中都要保存一份
 
面向对象类成员之方法

方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

  • 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self
  • 类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls
  • 静态方法:由调用;无默认参数;
#!/usr/bin/env python
#codencoding: utf-8
class Foo(object):
def __init__(self):
pass
def f1(self,arg): #普通方法,至少有1self参数
pass
@classmethod #定义为类方法
def f2(cls): #类方法,参数只能有1cls
pass
@staticmethod #定义为静态方法
def f3(arg1,arg2): #静态方法,参数任意
pass

obj=Foo()
obj.f1(20) #普通方法调用
Foo.f2() #类方法调用
Foo.f3(11,22) #静态方法调用

面向对象类成员之属性

由属性的定义和调用要注意一下几点:

  • 定义时,在普通方法的基础上添加 @property 装饰器;
  • 定义时,属性仅有一个self参数
  • 调用时,无需括号
               方法:foo_obj.func()
               属性:foo_obj.prop
 
#!/usr/bin/env python
#codencoding: utf-8
#分页
# ############### 定义 ###############
class Pager
:
def __init__
(
self,
index_page):
self
.index_page = index_page
#用户请求的页码
self
.page_itmes =
10            #每页默认显示10条数据
@property #定义为属性
def start
(
self
):
#计算页码从那条数据开始
#1,1 : 1页从第1条数据开始
#2,11 : 第2页从第11条数据开始
val = (
self
.index_page -
1
) *
self
.page_itmes +
1
return
val
@property   #定义为属性
def end
(
self
):
#计算页码从那条数据开始
#1,10 : 1页从第10条数据结束
#2,20 : 2页从第20条数据结束
val =
self
.index_page *
self
.page_itmes
return 
val
# ############### 调用 ###############
p = Pager(
1
)
print 
p.start
#p.start()方法加(),
属性不用加()
  
print
p.end

属性的两种定义方式

属性的定义有两种方式:

  • 装饰器 即:在方法上应用装饰器(上面例子)
  • 静态字段 即:在类中定义值为property对象的静态字段(下面例子)
 
#!/usr/bin/env python
#codencoding: utf-8
class Foo:
def fun(self):
return 'yangmv'
BAR = property(fun) #在类中定义值为property对象的静态字段

obj = Foo()
print obj.BAR

面向对象类成员修饰符
  • 公有成员,在任何地方都能访问
  • 私有成员,只有在类的内部才能方法   
  • 设置私有,字段或方法前加 __
 
设置私有字段
#!/usr/bin/env python
#codencoding: utf-8
class Foo:
__country = 'China' #__设置静态字段为私有
def func(self):
print Foo.__country #私有静态字段在内部可以被调用


#print Foo.country #私有静态字段country在外部无法被调用
obj = Foo()
obj.func()#!/usr/bin/env python
#codencoding: utf-8
class Foo:
def __init__(self):
self.__name = 'yangmv' #普通字段设为私有
def func(self):
print self.__name #内部可以被调用

obj = Foo()
#obj.__name #因此在外部也同样无法被调用
obj.func() #内部调用后输出

设置私有方法
#!/usr/bin/env python
#codencoding: utf-8
#私有普通方法
class Foo:
def __func(self): #设为私有方法
print 'china'
def func2(self):
self.__func() #通过内部调用__func 私有方法

obj = Foo()
#obj.__func #外部无法调用私有方法
obj.func2() #内部调用后输出
#!/usr/bin/env python
#codencoding: utf-8
#私有动态方法
class Foo:
@staticmethod #动态方法
def __func(): #设为私有动态方法
print 'china'
def func2(self):
Foo.__func() #通过内部调用__func 动态私有方法

obj = Foo()
obj.func2() #内部调用后输出
#Foo.__func #外部无法调用私有方法

子类不可以调用父类的私有字段

class Foo:
__country = 'China'

class Son:
def func(self):
print Foo.__country
#子类不可以调用父类的私有字段

强制访问私有字段或者方法对象._类__成员 obj._Foo__name    #强制调用私有字段 Foo._Foo_country
  #强制调用私有方法 

面向对象类的特殊成员

1. __doc__

  表示类的描述信息

 

2. __module__ 和  __class__ 

  __module__ 表示当前操作的对象在那个模块

  __class__     表示当前操作的对象的类是什么

 

3. __init__

  构造方法,通过类创建对象时,自动触发执行。

 

4. __del__

  析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

 

5. __call__

  对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类

 

#!/usr/bin/env python
#codencoding: utf-8
class Foo:

def __init__(self):
pass

def __call__(self, *args, **kwargs):

print '__call__'


obj = Foo() # 执行 __init__
obj() # 执行 __call__

6. __dict__

查看对象或类中有什么,并以字典的形式输出

 

#!/usr/bin/env python
#codencoding: utf-8
class Foo:
def __init__(self):
self.name = 'yangmv'
self.age = '20'
obj=Foo()
print obj.__dict__ #查看对象中
#print Foo.__dict__ #查看类

 


 

 

 7. __str__

  如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

 

class Foo:
def __str__(self):
return 'yangmv'
obj = Foo()
print obj
# 输出:yangmv。没有__str__的话输出内存地址




 



posted @ 2016-01-29 18:04  RootMe  阅读(421)  评论(0编辑  收藏  举报