您的位置:首页 > 编程语言 > Python开发

Python学习笔记:面向对象基础

2017-11-28 19:38 1826 查看

类、对象

class Role(object):
#类属性,不同对象的相同之处,省内存
name="XXX"
weapon="knife"
class_list=[]

#构造函数
def __init__(self,name,health=100):
#对象属性,不同对象的不同之处
self.name=name      #对象变量会覆盖类变量
#私有属性
self.__health=health

def buy(self,gun_code):
print("{} just bought {}.".format(self.name,gun_code))

def show_health(self):
print(self.__health)

#析构函数,对象销毁时自动执行,常用于关闭连接或内存回收
def __del__(self):
print("{} died.".format(self.name))


r1=Role("Jack")
r2=Role("Bob",health=120)


#访问属性与方法
print(r1.name,r1.weapon)
r2.show_health()
r1.buy("B51")


输出为:

Jack knife

120

Jack just bought B51.

#增加属性
r1.extra="bug"
print(r1.extra)


输出为:bug

#类变量
r1.weapon="gun"
print(Role.weapon,r1.weapon,r2.weapon)


输出为:

knife gun knife

r1.class_list.append("from r1")
r2.class_list.append("from r2")
print(Role.class_list,)


输出为:[‘from r1’, ‘from r2’]

del r1


输出为:Jack died.

继承

单继承

class People(object):
def __init__(self,name,age):
self.name=name
self.age=age

def show_info(self):
print(self.name,self.age)

class Man(People):
def __init__(self,name,age,Adams_apple):
super(Man,self).__init__(name,age)
self.Adams_apple=Adams_apple

def show_info(self):
print(self.name,self.age,self.Adams_apple)

class Woman(People):
def __init__(self,name,age,hair_cut):
super(Woman,self).__init__(name,age)
self.hair_cut=hair_cut

def show_info(self):
print(self.name,self.age,self.hair_cut)


man_1=Man("jack",22,True)
woman_1=Woman("ann",23,"long_hair")

man_1.show_info()
woman_1.show_info()


多继承

class People(object):
def __init__(self,name,age):
self.name=name
self.age=age

def show_info(self):
print(self.name,self.age)

class Relation(object):
def make_friends(self,Person_obj):
print("{} is making firends with {}.".format(self.name,Person_obj.name))

class Man(People,Relation):
def __init__(self,name,age,Adams_apple):
super(Man,self).__init__(name,age)
self.Adams_apple=Adams_apple

def show_info(self):
print(self.name,self.age,self.Adams_apple)

class Woman(People,Relation):
def __init__(self,name,age,hair_cut):
super(Woman,self).__init__(name,age)
self.hair_cut=hair_cut

def show_info(self):
print(self.name,self.age,self.hair_cut)


man_1,woman_2=Man("jack",22,True),Woman("ann",22,"long_hair")
man_1.make_friends(woman_2)


输出为:jack is making firends with ann.

多继承下的构造函数

python3下的多继承,对于构造函数的搜索机制为广度优先搜索。如上述代码中D先继承C再继承B,而C与B继承A。有以下几种情况:

A、B、C有构造函数,D无构造函数,实例化D时会输出C(D先继承C后继承B)

A、B有构造函数,C、D无构造函数,实例化D时会输出B(广度优先策略)

A有构造函数,B、C、D无构造函数,实例化D时会输出A

以上三种情况分别由下述代码证明。

#1.此时A中的构造函数不起作用
class B(object):
def __init__(self):
print("B")

class C(object):
def __init__(self):
print("C")

class D(C,B):
pass

object_1=D()


输出为:C

#2.D在C中找不到构造函数,转向同级父类B中寻找构造函数
class A(object):
def __init__(self):
print("A")

class B(A):
def __init__(self):
print("B")

class C(A):
pass

class D(C,B):
pass

object_1=D()


输出为:B

#3.D在同级父类B、C中均找不到构造函数,转向更高层的父类A中寻找
class A(object):
def __init__(self):
print("A")

class B(A):
pass

class C(A):
pass

class D(C,B):
pass

object_1=D()


输出为:A

类方法,静态方法,属性方法

实例方法

从上面的代码可以看到,示例方法在执行时会将自身对象当作self变量传给实例方法,如以下代码,dog对象调用eat()时,实际上会自动将dog这一对象变量作为参数传给eat()。

class Dog(object):
def __init__(self,name):
self.name=name

def eat(self):
print("{} is eating...".format(self.name))

dog=Dog("xiao huang")
dog.eat()


类方法

静态方法

而类中的静态方法相当于一个类中的自治方法,它虽然被包含在类中,但是却与类没有关联,静态方法无法访问类中的成员变量,如需访问,需要将对象变量作为参数传递给静态方法。将上述代码中的eat()换成静态方法后,想要正常调用eat()需要改为如下形式:

class Dog(object):
def __init__(self,name):
self.name=name

@staticmethod
def eat(self):
print("{} is eating...".format(self.name))

dog=Dog("xiao huang")
dog.eat(dog)    #此处若不传入dog会提示缺少参数


静态方法的使用场景为在有需要以多种方式进行实例化时,因为类只允许有一个__init__(),如果需要根据不同场景来实例化不同的对象(属于同一个类),可以使用静态方法。

比如一个时间类,需要三种实例化方法,默认方式为根据输入参数来获取时间,另一种方式为自动获取现在时间,示例代码如下:

import time

class Date(object):
def __init__(self,year,month,day):
self.year=year
self.month=month
self.day=day

def show_info(self):
print(self.year,self.month,self.day)

@staticmethod
def now():
date=time.localtime()
return Date(date.tm_year,date.tm_mon,date.tm_mday)

obj_1=Date("2012","12","12")
obj_2=Date.now()

obj_1.show_info()
obj_2.show_info()


输出为:

2012 12 12

2017 12 5

反射

反射机制实际上是字符串与内存地址之间的互相映射,为便于理解,先定义一个简单类:

class Dog(object):
def __init__(self,name):
self.name=name

def eat(self):
print("{} is eating...".format(self.name))

dog=Dog("xiaohuang")


假设有这么一个需求,对于狗的实例对象”xiaohuang”,需要根据用户的输入来调用狗这个类中的方法,简单的一个做法是使用if来进行条件判断,但这种做法显然是不可取的。因为如果类中有一千种方法,则需要写一千个if判断;并且用户的输入为字符串格式,对象也是无法直接使用字符串来调用内部属性的。这种场景就需要用到对象的反射机制,具体代码如下:

choice=input(">>:").strip()        #以字符串形式保存用户想要调用的属性
if(hasattr(dog,choice)):        #判断dog对象是否有对应属性
func=getattr(dog,choice)        #获取dog中的对应方法
func()


运行结果:



现在又有一个需求,如果用户指定的方法不存在,则在类中添加一个方法,新方法在执行之后删除。修改后的代码如下:

def bark(self):
print("{} is barking...".format(self.name))

choice=input(">>:").strip() #以字符串形式保存用户想要调用的属性 if(hasattr(dog,choice)): #判断dog对象是否有对应属性 func=getattr(dog,choice) #获取dog中的对应方法 func()
else:
setattr(dog,choice,bark) #setattr(x,y,v):设置x.y=v
func=getattr(dog,choice)
func(dog)
delattr(dog,choice) #删除新增的属性


输出为:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python