声明:代码的运行环境为Python3。Python3与Python2在一些细节上会有所不同,希望广大读者注意。本博客以代码为主,代码中会有详细的注释。相关文章将会发布在我的个人博客专栏《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)的变量, 只能是允许这个类本身进行访问了
你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。