Python 面向对象
面向对象技术简介
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 实例变量:定义在方法中的变量,只作用于当前实例的类。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 方法:类中定义的函数。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
创建类
使用class语句来创建一个新类,class之后为类的名称并以冒号结尾,如下实例:
类的帮助信息可以通过ClassName.doc查看。
class_suite 由类成员,方法,数据属性组成。
实例
- empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Employee.empCount 访问。
- 第一种方法init()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
- self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
- self代表类的实例,而非类
- 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
创建实例对象
实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式。
以下使用类的名称 Employee 来实例化,并通过 __init__
方法接受参数。
访问属性
您可以使用点(.)来访问对象的属性。使用如下类的名称访问类变量:
完整实例:
执行以上代码输出结果如下:
你可以添加,删除,修改类的属性,如下所示:
你也可以使用以下函数的方式来访问属性:
- getattr(obj, name[, default]) : 访问对象的属性。
- hasattr(obj,name) : 检查是否存在一个属性。
- setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
- delattr(obj, name) : 删除属性。1234hasattr(emp1, 'age') # 如果存在 'age' 属性返回 True。getattr(emp1, 'age') # 返回 'age' 属性的值setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8delattr(empl, 'age') # 删除属性 'age'
Python内置类属性
__dict__
: 类的属性(包含一个字典,由类的数据属性组成)__doc__
:类的文档字符串__name__
: 类名__module__
: 类定义所在的模块(类的全名是’__main__.className
‘,如果类位于一个导入模块mymod中,那么className.__module__
等于 mymod)__bases__
: 类的所有父类构成元素(包含了一个由所有父类组成的元组)
Python内置类属性调用实例如下:
执行以上代码输出结果如下:
类的继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
需要注意的地方:继承语法 class 派生类名(基类名)://… 基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。
在python中继承中的一些特点:
- 在继承中基类的构造(init()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
- Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
如果在继承元组中列了一个以上的类,那么它就被称作”多重继承” 。
语法:
派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:123class SubClassName (ParentClass1[, ParentClass2, ...]):'Optional class documentation string'class_suite
实例
以上代码执行结果如下:
你可以继承多个类
你可以使用issubclass()或者isinstance()方法来检测。
- issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
- isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。
方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:
实例:12345678910111213#!/usr/bin/python# -*- coding: UTF-8 -*-class Parent: # 定义父类def myMethod(self):print '调用父类方法'class Child(Parent): # 定义子类def myMethod(self):print '调用子类方法'c = Child() # 子类实例c.myMethod() # 子类调用重写方法
执行以上代码输出结果如下:
基础重载方法
下表列出了一些通用的功能,你可以在自己的类重写:
序号 方法, 描述 & 简单的调用
运算符重载
Python同样支持运算符重载,实例如下:
实例
以上代码执行结果如下所示:
类属性与方法
类的私有属性
private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.private_attrs。
类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.private_methods
实例
Python 通过改变名称来包含类名:
Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName 访问属性,将如下代码替换以上代码的最后一行代码:
执行以上代码,执行结果如下:
单下划线、双下划线、头尾双下划线说明:
__foo__
: 定义的是特列方法,类似__init__()
之类的。_foo
: 以单下划线开头的表示的是protected
类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于from module import *
__foo
: 双下划线的表示的是私有类型(private
)的变量, 只能是允许这个类本身进行访问了。
Python 函数
Python 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
语法
参数传递
在 python 中,类型属于对象,变量是没有类型的:
以上代码中,[1,2,3] 是 List 类型,”Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是 List 类型对象,也可以指向 String 类型对象。
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
- 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
python 传不可变对象实例:
传可变对象实例
实例中传入函数的和在末尾添加新内容的对象用的是同一个引用,故输出结果如下:
参数
以下是调用函数时可使用的正式参数类型:
- 必备参数
- 关键字参数
- 默认参数
- 不定长参数
必备参数
必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用printme()函数,你必须传入一个参数,不然会出现语法错误
关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 printme() 调用时使用参数名:
输出结果:
缺省参数
调用函数时,缺省参数的值如果没有传入,则被认为是默认值。下例会打印默认的age,如果age没有被传入:
输出结果:
不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:
加了星号(*)的变量名会存放所有未命名的变量参数。选择不多传参数也可。如下实例:
以上实例输出结果:
匿名函数
python 使用 lambda 来创建匿名函数。
- lambda只是一个表达式,函数体比def简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法:
实例:
Python 基础
Python 标识符
- 在 Python 里,标识符由字母、数字、下划线组成。
- 在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。
- Python 中的标识符是区分大小写的。
- 以下划线开头的标识符是有特殊意义的。以单下划线开头
_foo
的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用from xxx import *
而导入; - 以双下划线开头的
__foo
代表类的私有成员; - 以双下划线开头和结尾的
__foo__
代表 Python 里特殊方法专用的标识,如__init__()
代表类的构造函数。
标准数据类型
在内存中存储的数据可以有多种类型。
例如,一个人的年龄可以用数字来存储,他的名字可以用字符来存储。
Python 定义了一些标准类型,用于存储各种类型的数据。
Python有五个标准的数据类型:
- Numbers(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Dictionary(字典)
Python列表
List(列表) 是 Python 中使用最频繁的数据类型。
- 列表可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串甚至可以包含列表(即嵌套)。
- 列表用 [ ] 标识,是 python 最通用的复合数据类型。
- 列表中值的切割也可以用到变量 [头下标:尾下标] ,就可以截取相应的列表,从左到右索引默认 0 开始,从右到左索引默认 -1 开始,下标可以为空表示取到头或尾。
- 加号 + 是列表连接运算符,星号 * 是重复操作。如下实例:123456789101112#!/usr/bin/python# -*- coding: UTF-8 -*-list = [ 'runoob', 786 , 2.23, 'john', 70.2 ]tinylist = [123, 'john']print list # 输出完整列表print list[0] # 输出列表的第一个元素print list[1:3] # 输出第二个至第三个的元素print list[2:] # 输出从第三个开始至列表末尾的所有元素print tinylist * 2 # 输出列表两次print list + tinylist # 打印组合的列表
以上实例输出结果:
Python元组
元组是另一个数据类型,类似于List(列表)。
元组用”()”标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。
Python 字典
字典(dictionary)是除列表以外python之中最灵活的内置数据结构类型。列表是有序的对象结合,字典是无序的对象集合。
两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
字典用”{ }”标识。字典由索引(key)和它对应的值value组成。
输出结果为:
Python数据类型转换
有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。
以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。
Python运算符优先级
以下表格列出了从最高到最低优先级的所有运算符:
Python While 循环语句
Gif 演示 Python while 语句执行过程
循环使用 else 语句
在 python 中,for … else
表示这样的意思,for
中的语句和普通的没有区别,else
中的语句会在循环正常执行完(即 for
不是通过 break
跳出而中断的)的情况下执行,while … else
也是一样。
以上实例输出结果:
|
|
机器学习(三)
机器学习(二)
无监督学习
利用无标签的数据学习数据的分布或数据与数据之间的关系被称作无监督学习
- 有监督学习和无监督学习的最大区别在于数据是否有标签
- 无监督学习最常用的场景是聚类(clustering)和降维(Dimension Reduction)
聚类(clusterinng)
聚类,就是根据数据的“相似性”将数据分为多类的过程,通过计算两个样本之间的“距离”来评估两个不同样本之间的“相似性”,使用不同的方法计算样本间的距离会关系到聚类结果的好坏。
欧式距离
欧氏距离:
机器学习(一)
机器学习简介
机器学习的目标
机器学习是实现人工智能的手段,其主要目的是利用数据和经验进行学习,改善具体算法的性能
- 多领域交叉,涉及概率论、统计学、算法复杂度理论
- 广泛应用于 网络搜索、垃圾邮件过滤 、推荐 系统、广告投放信用 评价 、 欺诈检测、股票交易 和医疗诊断等
机器学习分类
- 监督学习 (Supervised Learning)
- 无监督学习(Unsupervised Learning)
- 强化学习(Reinforcement Learning)
- 半监督学习(Semi-supervised)
- 深度学习(Deep Learning)
Python Scikit-learn
用于解决机器学习过程中的算法,是一组工具集
Scikit-learn 常用函数
初识Markdown
快速入门(完整文档点击这里)
段落、标题、区块代码
- 段落是由一个以上的连接的行句组成,而一个以上的空行则会划分出不同的段落(空行的定义是显示上看起来像是空行,就被视为空行,例如有一行只有空白和 tab,那么该行也被视为空行),一般的段落不需要空白或换行缩进。
- 标题 有两种写法,Setext和atx形式。Setext形式是用底线的形式,利用
=
(最高阶标题)和-
(第二阶标题),Atx形式在行首插入1到6个#
,对应标题1到6阶。 - 区块 引用则使用email形式的
>
角括号。
Markdown语法:
|
|
输出HTML为:
|
|
效果显示:
修辞和强调
Markdown 使用*
和_
来标记需要强调的区段
Markdown语法:
|
|
输出HTML为:
列表
无序列表使用
*
,+
,-
来作为列表额项目标记,这些符号都是可以使用的。有序列表使用数字加
.
来作为列表额项目标记,这些符号都是可以使用的。如果你在项目之间插入空行,那项目的内容会用
<p>
包起来,你也可以在一个项目内放上多个段落,只要在它前面缩排 4 个空白或 1 个 tab 。
Markdown语法:
输出HTML为:
链接
Markdown 支持两种形式的链接语法:行内和参考两种形式,两种都是使用角括号把文字转成连接。
Markdown语法:
输出HTML为:
|
|
图片
图片的语法和链接很像,也分为行内和参考
Markdown语法:
输出HTML为:
代码
在一般的段落文字中,可以使用(`)
来标记代码区段,区段内的&
、<
和>
也一样会自动转成HTML实体。
Markdown语法:
输出HTML为: