声明:代码的运行环境为Python3。Python3与Python2在一些细节上会有所不同,希望广大读者注意。本博客以代码为主,代码中会有详细的注释。相关文章将会发布在我的个人博客专栏《Python从入门到深度学习》,欢迎大家关注。
目录
二、Python机器学习基础之Python的基本语法(二)
通过前面的第一讲,相信大家对Python已经有了基本的了解。下面开始我们的第二讲:Python机器学习基础之Python的基本语(二)。
【代码】
'''
机器学习基础之Python的基本语法02
'''
# 函数:函数代码块以def 关键词开头,函数内容以冒号起始,并且缩进。函数的第一行语句可以是字符串,用于函数说明。
# return [表达式]结束函数,不带返回值表达式的相当于返回None
# 语法:
# def functionname(parameters):
# "函数_文档字符串"
# function_suite
# return [expression]
def printme(s):
'''
打印传入的字符串
:param s:
:return:
'''
print(s)
return s
printme('abc')
# 参数传递:对于不可变类型:类似c++的值传递,如整数、字符串、元组。如fun(a),传递的只是a的值, 没有影响a对象本身。
# 比如在fun(a)内部修改a的值,只是修改另一个复制的对象,不会影响a本身。
def ChangeInt(a):
a = 10
b = 2
ChangeInt(b)
print(b) # 结果是 2
# 对于可变类型:类似c++的引用传递,如列表,字典。如fun(list),则是将list真正的传过去,修改后fun外部的list也会受影响
def changeme(mylist):
mylist.append(50)
print(mylist)
return
mylist = [10, 20, 30]
changeme(mylist)
print(mylist)
# python中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象
# 通过参数名赋参
def printinfo(name, age):
print("Name: ", name)
print("Age ", age)
return
printinfo(age=22, name="xzw")
# 默认参数
def printinfo(name, age=35):
print("Name: ", name)
print("Age ", age)
return
printinfo(age=50, name="miki")
printinfo("miki")
# 变长参数
def printinfo(arg1, *vartuple):
print("输出: ")
print(arg1)
for x in vartuple:
print(x)
return
printinfo(10)
printinfo(20, 30, 40, 50)
# lambda函数:lambda只是一个表达式,函数体比def简单很多;lambda主体是一个表达式,而不是一个代码块,仅仅能在lambda表达式中封装有限的逻辑进去;
# lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数;Python仅仅将lambda
# 定位成一个辅助用的短函数,所以lambda只能写一行,不能赋值,内部也不能定义等
sum = lambda arg1, arg2: arg1 + arg2
print(sum(10, 20))
def makeSum():
sum = lambda arg1, arg2: arg1 + arg2
return sum
f = makeSum()
print(f(10, 20))
# 返回值
def sum(arg1, arg2):
total = arg1 + arg2
print("函数内 : ", total)
return total
total = sum(10, 20)
print("函数外 : ", total)
# 函数类型参数
def add(x, y, f):
return f(x) + f(y)
print(abs(-3)) # 绝对值
print(add(-3, 5, abs)) # 当函数作为参数时,不可以加()
# 全局变量和局部变量:定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
total = 0 # 这是一个全局变量
def sum(arg1, arg2):
# total = arg1 + arg2; #注意此处注解取消后的不同,若有同名变量的话,局部变量的优先级高于全局变量
print(total)
return total
sum(10, 20)
print(total)
# global:将函数内变量定义为全局变量,可以通过定义为全局变量,实现在函数内部改变变量值
# globvar = 0 #此处globvar的定义可有可无
def set_globvar_to_one():
global globvar # 使用 global 声明全局变量
globvar = 1
def print_globvar():
print(globvar) # 没有使用 global
set_globvar_to_one()
print(globvar) # 输出 1
print_globvar() # 输出 1,函数内的 globvar 已经是全局变量
# 模块:Python模块(Module),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句模块让你能够有逻辑地组织你的Python,代码段
# 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。模块能定义函数,类和变量,模块里也能包含可执行的代码
# support.py
# support模块
def print_func(s):
print("Hello : ", s)
return
# hello.py
# # 方式一
# import support
#
# support.print_func("Tom")
#
# # 方式二
# from support import print_func
#
# print_func("Tom")
#
# # 方式三
# from support import *
#
# print_func("Tom")
# 输入与类型转换
import sys
# 输入一个字符串
# s=sys.stdin.readline() # 手动输入
# print(s) #输入字符串的末尾会多出一个字符'\n',例如,输入的是'abc',得到的是'abc\n',因此长度会加1
s = '100'
a = int(s)
b = float(a)
b += 1
s = str(b)
print(s)
# 命名空间和作用域:变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典。
# 一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。
# 每个函数都有自己的命名空间。类的方法的作用域和通常函数的一样。
# 包:包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的Python的应用环境。简单来说,包就是文件夹,该文件夹下必须存在
# __init__.py文件, 其内容可以为空,__int__.py用于标识当前文件夹是一个包。目录结构如下:
# hello.py
# mypackage(文件夹)
# | -- __init__.py
# | -- runoob1.py
# | -- runoob2.py
#
# runoob1.py:
# def f1():
# print("I'm in runoob1")
#
# runoob2.py
# def f2():
# print("I'm in runoob2")
# hello.py:
# from mypackage.runoob1 import f1
# from mypackage.runoob2 import f2
#
# f1()
# f2()
#
# import sys
#
# s = sys.stdin.readline()
# print(s)
# 异常处理:BaseException: 所有异常的基类
try:
print(1 / 0)
except IOError:
print("IOError")
except ZeroDivisionError:
print("ZeroDivisionError")
else: # 无异常时
print("esle")
finally:
print("finally")
# 类 :类方法必须包含参数self, 且为第一个参数
class Employee:
'所有员工的基类' # 第一行可以用字符串来做说明
# empCount是一个类变量,在这个类的所有实例之间共享,使用Employee.empCount来访问
empCount = 0
# 构造器
# self代表类的实例,在定义时必须有,在调用时不必传值
# 参数为属性
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self): # self不可以省略
print("Total Employee %d" % Employee.empCount)
def displayEmployee(self):
print("Name : ", self.name, ", Salary: ", self.salary)
a = Employee("zhangsan", 5000)
print(Employee.empCount, a.name, a.salary)
a.age = 26 # 添加属性
print(a.age)
del a.age # 删除属性
# print(a.age)
b = Employee("lisi", 5000)
print(Employee.empCount, b.name, b.salary)
b.displayCount()
b.salary = 6000
b.displayEmployee()
print(b)
# 关于self:self代表的是类的实例,代表当前对象的地址,而runoob.__class__指向类。self不是关键字,换成其他也可以,如:runoob
class Test:
def myprint(runoob):
print(runoob)
print(runoob.__class__)
t = Test()
t.myprint()
# 内置类属性
# __doc__: 类的文档字符串
# __name__: 类名
# __module__: 类定义所在的模块 (类的全名是
# '__main__.className',如果类位于一个导入模块mymodule中,那么__module__即为
# mymodule)
# __bases__: 类的所有父类构成元素(包含了一个由所有父类组成的元组)
# __dict__: 类的属性(包含一个字典,由类的数据属性组成)
class Employee:
'雇员类'
empCount = 0
print("Employee.__doc__:", Employee.__doc__)
print("Employee.__name__:", Employee.__name__)
print("Employee.__module__:", Employee.__module__)
print("Employee.__bases__:", Employee.__bases__)
print("Employee.__dict__:", Employee.__dict__)
# python对象销毁(垃圾回收):Python使用了引用计数这一简单技术来跟踪和回收垃圾。在Python内部记录着所有使用中的对象各有多少引用,
# 当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0时, 它被垃圾回收。但是回收不是"立即"
# 的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。如:
a = 40 # 创建对象 <40>
b = a # 增加引用, <40> 的计数
c = [b] # 增加引用. <40> 的计数
del a # 减少引用 <40> 的计数
b = 100 # 减少引用 <40> 的计数
c[0] = -1 # 减少引用 <40> 的计数
# 析构函数:析构函数__del__在对象销毁的时候被调用
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print(class_name, "销毁")
pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3)) # 打印对象的id
del pt1
del pt2
del pt3
# 继承:基类构造器(__init__())不会被自动调用,Python先在本类中查找调用的方法,找不到才去基类中找,如果在继承元组中列了一个以上的类,那么它就被称作"多重继承"
class Parent: # 父类
parentAttr = 100
def __init__(self):
print("调用父类构造函数")
def parentMethod(self):
print('调用父类方法')
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print("父类属性 :", Parent.parentAttr)
class A:
a = 0
class Child(Parent, A): # 子类,多重继承
def __init__(self):
print("调用子类构造方法")
def childMethod(self):
print('调用子类方法')
c = Child() # 实例化子类
c.childMethod() # 调用子类的方法
c.parentMethod() # 调用父类方法
c.setAttr(200) # 再次调用父类的方法 - 设置属性值
c.getAttr() # 再次调用父类的方法 - 获取属性值
# 方法重写
class Parent: # 定义父类
def myMethod(self):
print('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
# 运算符重载:注意:Python不支持函数重载。
# 常见重载方法:
# Method Overloads Call for
# ------ ---------- ---------
# __init__ 构造函数 X=Class()
# __del__ 析构函数 对象销毁
# __add__ + X+Y,X+=Y
# __sub__ - X-Y,X-=Y
# __or__ | X|Y,X|=Y
# __repr__ 打印转换 print X,repr(X)
# __str__ 打印转换 print X,str(X)
# __call__ 调用函数 X()
# __getattr_ 限制 X.undefine
# __setattr__ 取值 X.any=value
# __getitem__ 索引 X[key],
# __len__ 长度 len(X)
# __cmp__ 比较 X==Y,X<Y
# __lt__ 小于 X<Y
# __eq__ 等于 X=Y
# __radd__ Right-Side + +X
# __iadd__ += X+=Y
# __iter__ 迭代 For In
# 加号重载
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10)
v2 = Vector(6, 1)
print(v1 + v2)
# 减号重载
class Number:
def __init__(self, start):
self.data = start # 添加属性
def __sub__(self, other): # minus method
return Number(self.data - other)
number = Number(30)
y = number - 10
print(y.data) # 20
# 私有:私有属性:两个下划线开头,不能在类的外部使用,类内部使用时用self.__XXX。但可以使用object._className__attrName来访问私有属性
# 私有方法:两个下划线开头,不能在类的外部调用,类内部调用时用self.__private_methods
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公有变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)
counter = JustCounter()
counter.count()
print(counter.publicCount)
# print(counter.__secretCount) #错误
print(counter._JustCounter__secretCount)
# 单下划线、双下划线、头尾双下划线说明:
# 1、 __XXX__: 定义的是特殊方法,如 __init__() 之类
# 2、 _foo: 以单下划线开头的表示的是 protected 类型的变量,
# 即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
# 3、 __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了
你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。