机器学习基础之Python的基本语法(二)

      声明:代码的运行环境为Python3。Python3与Python2在一些细节上会有所不同,希望广大读者注意。本博客以代码为主,代码中会有详细的注释。相关文章将会发布在我的个人博客专栏《Python从入门到深度学习》,欢迎大家关注。


目录

一、机器学习基础之Python的基本语法(一)

二、机器学习基础之Python的基本语法(二)

三、机器学习基础之Numpy库的使用


       通过前面的第一讲,相信大家对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)的变量, 只能是允许这个类本身进行访问了

你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。

猜你喜欢

转载自blog.csdn.net/gdkyxy2013/article/details/80230492