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

机器学习之python基础(五)

2015-11-06 21:19 831 查看

机器学习之python基础(五)





综述

这一系列博客是记录我在学习python和机器学习的过程中的一些实践过程和体会,学习python时用到的参考书籍是《python学习手册 第四版》,即《learning python》的中文版。学习机器学习时所用的主要参考书籍是《机器学习实战》,还参考了CSDN博客平台上博客名为zouxy09的部分博客文章(博客后面附有url链接),实现其中的各种算法所使用的程序语言是python,实验平台是Ubuntu14.04,所使用的python版本是2.7.6。如果有博友想要与我进行交流可以在博客后面留言,或者发邮件到我的邮箱zouchaobin@foxmail.com。由于python3.0以后的版本与python3.0之前的版本有较大改变,所以为了某些代码的兼容性(如print函数),也为了便于直接使用《python学习手册》中的源代码(这本书的源代码是基于python3.x的),我决定采用以下处理方式:

from __future__ import print_function
from __future__ import division

在每个代码文件的开头加入以上两行代码,这样的话就可以使用python3.x的print函数和除法运算了,这样便于将这些代码稍加修改就能移植到python3.x的平台上。

python类

在python中,面向对象程序设计(OOP)完全是可选的,并且在初学阶段不需要使用类(class),不使用类也可以做许多事情,并且可以快速开发和维护,但是实际上类可以大量减少开发时间,对于那些需要长期维护的大型软件来说是必要的。类可以被继承,python中的超类(C++中的基类)与子类(C++中的派生类)是继承和派生的关系,可以最大程度上重用代码;可以将许多类型组合到一起成为新的类型;可以重载运算符,在最大程度上满足用户的需求。
python中的类使用起来十分简单明了,没有太多的语法杂质,复杂性比C++/java等大大降低,python中大多数类的使用都可以简化成以下表达式:
objec.attribute
上面整个语句在整个执行过程中等同于:找出attribute首次出现的地方,先搜索object,然后是该对象之上的所有类,从下至上,从左至右。换句话说,取出属性只是简单地搜索“树”而已。
如下图所示:



I1,I2是类C1的子类,C1是超类C2和超类C3的子类,C1继承了C2和C3的所有属性,I1和I2继承了C1的所有属性,那么在这个树中,当I2调用object.attribute进行属性搜索时的搜索顺序为:I2,C1,C2,C3,I1则为I1,C1,C2,C3。如下所示:
I1.x和I2.x两者都会在C1中找到x并停止搜索,因为C1比C2位置更低(事实上C1已经重新定义了x属性来取代了从C2中继承的属性x)。
I1.y和I2.y两者都会在C1中找到y,因为这里是y唯一出现的地方。
I1.z和I2.z两者都会在C2中找到z,因为C2比C3更靠左。
I2.name会找到I2中的name,不需要“爬树”。

编写类树:
1,每个class语句会生成一个新的类对象。
2,每次类调用时,就会产生一个新的实例对象。
3,实例自动连接至创建了这些实例的类。
4,类连接至超类的方式是将超类列在类头部的括号内,其从左至右的顺序会决定树中的次序。

下面是一个简单的类实验:

类person的定义如下:

class person:
def __init__(self, n, a):
self.name = n
self.age = a
def set_name(self,n):
self.name = n
def set_age(self,a):
self.age = a
def display(self):
print('name:', self.name, 'age:', self.age, sep=' ')
person类包含名字和年龄两个属性,采用了__init__函数来构造对象。

# -*- coding: utf-8 -*-
from __future__ import print_function from __future__ import division

from class_person import person

p = person('Tom', 22)
p.display()

p.set_name('Bob')
p.set_age(23)
print(p.name)
print(p.age)
运行结果如下:



类最大的优点体现在代码的重用上,代码的重用在类中体现为类的继承,但是需要注意的是类的封装性要好。本类的变量原则上只能由本类的属性方法可以直接访问,其继承类(子类)要想访问超类(基类)的变量必须通过属性方法来访问,而不可以直接操作,这样可以有更好的封装性。

下面这个实例说明了类的继承方式和方法,首先有一个超类Person,这个超类有2个子类Staff和Student,这2个子类又有一个公共的子类Staff_student,继承关系如下图所示:



下面分别是4个类的源代码:

# -*- coding: utf-8 -*-
class Person:
def __init__(self, n, a):
self.name = n
self.age = a
def set_name(self,n):
self.name = n
def get_name(self):
return(self.name)
def set_age(self,a):
self.age = a
def get_age(self):
return(self.age)
def display(self):
print('name:',self.name)
print('age',self.age)
<pre name="code" class="python"># -*- coding: utf-8 -*-
from class_person import Person

class Staff(Person):
def __init__(self,n,a,j,p):
#继承的属性
self.person = Person(n, a)

#新的属性
self.job = j
self.pay = p
def set_name(self,n):
self.person.set_name(n)
def get_name(self):
return(self.person.get_name())
def set_age(self,a):
self.person.set_age(a)
def get_age(self):
return(self.person.get_age())
def set_job(self, j):
self.job = j
def get_job(self):
return(self.job)
def set_pay(self, p):
self.pay = p
def get_pay(self):
return(self.pay)
def display(self):
self.person.display()
print('job:',self.job)
print('pay:',self.pay)




# -*- coding: utf-8 -*-
from class_person import Person

class Student(Person):
def __init__(self, n, a, m, s):
#继承的属性
self.person = Person(n, a)

#新的属性
self.major = m
self.school = s
def set_name(self,n):
self.person.set_name(n)
def get_name(self):
return(self.person.get_name())
def set_age(self,a):
self.person.set_age(a)
def get_age(self):
return(self.person.get_age())
def set_major(self,m):
self.major = m
def get_major(self):
return(self.major)
def set_school(self,s):
self.school = s
def get_school(self):
return(self.school)
def display(self):
self.person.display()
print('major:', self.major)
print('school:', self.school)


# -*- coding: utf-8 -*-
from class_staff import Staff
from class_student import Student

class Staff_student(Staff, Student):
def __init__(self, n, a, j, p, m, s, m_s):
#继承的属性
self.staff = Staff(n,a,j,p)
self.student = Student(n,a,m,s)

#新的属性
self.marry_status = m_s
def set_name(self,n):
self.staff.set_name(n)
def get_name(self):
return(self.staff.get_name())
def set_age(self,a):
self.staff.set_age(a)
def get_age(self):
return(self.staff.get_age())
def set_job(self, j):
self.staff.set_job(j)
def get_job(self):
return(self.staff.get_job())
def set_pay(self, p):
self.staff.set_pay(p)
def get_pay(self):
return(self.staff.get_pay())
def set_major(self,m):
self.student.set_major(self,m)
def get_major(self):
return(self.student.get_major())
def set_school(self,s):
self.student.set_school(s)
def get_school(self):
return(self.student.get_school())
def set_marry_status(self, yes_or_no):
self.marry_status = yes_or_no
def get_marry_status(self, yes_or_no):
return(self.marry_status)
def display(self):
self.staff.display()
self.student.display()
print("marry status:", self.marry_status)


测试程序如下:

<pre name="code" class="python"># -*- coding: utf-8 -*-
from __future__ import print_function from __future__ import division

print('----------------')
print("staff:")
from class_staff import Staff

sta = Staff('Tom', 22, 'teacher', 2000)
sta.display()
sta.set_name('Tom Tomas')
sta.set_job('engineer')
sta.set_pay(40000)
print(">>>>after modifing...")
sta.display()

print('----------------')
print("student:")
from class_student import Student

stu = Student('Bob', 23, 'Automation', 'UESTC')
stu.display()
stu.set_name('Bob J')
stu.set_age(18)
stu.set_school('USTC')
print(">>>>after modifing...")
stu.display()

print('----------------')
print("staff_student:")
from class_staff_student import Staff_student

sta_stu = Staff_student('Merry', 25, 'teacher', 3000, 'Automation', 'UESTC', 'no')
sta_stu.display()
sta_stu.set_name('Merry Obama')
sta_stu.set_age(28)
sta_stu.set_job('professor')
sta_stu.set_pay(100000)
sta_stu.set_marry_status('yes')
print(">>>>after modifing...")
sta_stu.display()



在我看来,每一个类都应该受到保护,不能在类外直接访问类的成员或属性,应该通过类定义的属性方法来访问和修改。比如上面在类中如果要访问name属性,则应该通过get_name依次往上访问到Person内部的name属性。

以下是运行结果:



python中的类同样还有许多的高级方法,但作为基础学习此处按下不表,更多有关python类的学习请参考《python学习手册》第四版。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: