一个java程序员的python之旅----初识

[TOC]

记录一下自己的python学习之旅,入门书籍为《python编程:从入门到实践》,运行环境为python3.6.3。也有一定的编程基础,对于一些通用的语法不再赘述,本篇主要记录一下python一些不同于java的基本语法

书写格式

  • 一句代码的结束以换行为标志,不需要分号。
  • 建议每级缩进都使用四个空格。
  • 建议每行不超过80字符,建议注释的行长不超过72字符。
  • 不同的逻辑之间可用一个空行隔开。
  • 代码块不需要大括号,python根据缩进来判断代码行与前一个代码行的关系。
  • python变量和函数命名习惯采用小写,可用下划线隔开,不像java采用驼峰命名法。
  • 在条件测试的格式设置方面,建议在诸如== 、>= 和<= 等比较运算符两边各添加一个空格。

基本数据类型

  • Number(数字)
    1. int(整型)
    2. long(长整型)
    3. float(浮点型)
    4. complex(复数)
  • String(字符串)
  • List(列表)
  • Tuplc(元组)
  • Dictionary(字典)

常用计算符号

  • +,加号
  • -,减号
  • *,乘号
  • /,除号
  • %,取余
  • //,整除
  • **,乘方

变量

变量不需要声明。

message = "Hello Python"
print(message)

字符串

  • 字符串可以用双引号,也可以用单引号,这样可以方便的在字符串中使用引号,当然也可以像java一下通过转义字符表示引号。
  • 下标从左到右从0开始,从右到左从-1开始,-1表示最后一个字符。
  • 截取字符串使用 str[开始下标 :结束下标]
  • python中的字符串也封装了许多的基本操作方法,比如大小写转换,去首尾空格等,可以在使用过程中慢慢去熟悉。
message = " Hello world "
print(message.title())  # 首字母大写
print(message.lower())  # 转换小写
print(message.upper())  # 转换大写
print(message.count("o"))  # 字符计数
print(message.strip())  # 去首尾空格
print(message.lstrip())  # 去开头空格
print(message.rstrip())  # 去结尾空格
print(message.__len__())  # 字符串长度

数字

  • 数字和字符串不能直接拼接。
print("Hello " + 213)  # TypeError: must be str, not int
print("Hello " + str(213))  # Hello 213

整数

  • python中可以用 ** 表示乘方运算
  • python3中两个整数相除时,会得到真实的结果,而python2中只会得到整数部分,这与java类似(3/2=1)。
print(2 ** 3)  # 8
print(3 / 2)  # 1.5
print(4 / 3)  # 1.3333333333333333

注释

  • python中注释用#来表示。

列表

有序集合,用[]表示。类似于但又不同于java中的数组、集合。

  • python中的列表不要求数据类型相同,及不用类型的数据可以放到同一个列表中,姑且简单理解为List
  • 有序集合,因此支持按索引访问,索引从0开始。不同的是python还支持反向索引,-1代表最后一个数据,-2代表倒数第二个,依次类推。
  • names = ["Allen", "Toto", 123]
    print(names)  # ['Allen', 'Toto', 123]
    print(names[1])  # Toto
    print(names[-1])  # 123
    
    • 修改元素:类似于java数组,直接通过索引赋值修改。
    • 添加元素:提供append和insert方法,分别用于在列表末尾追加和在指定索引位置插入新元素。也可以通过extend方法直接在末尾追加一个列表。
    • 删除元素:提供pop和remove方法,分别用于删除指定索引和指定值的元素。也可用del语句来删除。注意remove方法只是删除一个元素,如果列表中有多个相同元素,可以通过循环删除。
    names = ["Allen", "Toto", 123]
    print(names)  # ['Allen', 'Toto', 123]
    names[2] = 456
    print(names)  # ['Allen', 'Toto', 456]
    names.append(True)
    print(names)  # ['Allen', 'Toto', 456, True]
    names.insert(1, 123)
    print(names)  # ['Allen', 123, 'Toto', 456, True]
    del names[-1]
    print(names)  # ['Allen', 123, 'Toto', 456]
    test = names.pop(-1)
    print(names)  # ['Allen', 123, 'Toto']
    print(test)  # 456
    names.remove("Allen")
    print(names)  # [123, 'Toto']
    
    • 排序:注意只有所有元素为相同类型的列表可以排序。可以通过列表的sort方法或者sorted函数来进行排序,其中sort会改变原列表,sorted不会改变原列表。也可以通过参数来控制顺序。
    names = ["Allen", "Toto", "Lili"]
    names.sort()
    print(names)  # ['Allen', 'Lili', 'Toto']
    names.sort(reverse=True)
    print(names)  # ['Toto', 'Lili', 'Allen']
    print(sorted(names))  # ['Allen', 'Lili', 'Toto']
    print(names)  # ['Toto', 'Lili', 'Allen']
    
    • 遍历:通过for循环进行遍历,类似于java中的foreach语句,仅仅是写法不同。
    names = ["Allen", "Toto", "Lili"]
    for item in names:  # 注意最后有个冒号,代码块需要缩进
        print(item)
    

    如果需要对索引和值同时迭代,可以使用python内置的enumerate函数:

    names = ["Allen", "Toto", "Lili"]
    for index,item in enumerate(names):  # 注意最后有个冒号,代码块需要缩进
        print(index,item)
    
    • 数值列表:python使用range函数可以很方便的创建一个数值列表,结果符合编程中最常见的差一行为,比如range(1,6),实际生成的为1到5这五个数字。
    nums = list(range(1, 6))  # 创建数值列表
    print(nums)  # [1, 2, 3, 4, 5]
    # range还支持步数
    nums = list(range(1, 6, 2))  # [1, 3, 5]
    print(nums)
    
    • 列表解析:将for循环和创建新元素的代码合并成一行,并自动附加新元素。下面两种写法是等价的。
    nums = list()
    for item in range(1, 6):
        nums.append(item ** item)
    print(nums)  # [1, 4, 27, 256, 3125]
    
    # 列表解析的格式为[表达式 + for循环]
    nums = [item ** item for item in range(1, 6)]
    print(nums)  # [1, 4, 27, 256, 3125]
    
    • 切片:即截取列表的部分相邻元素。通过指定要截取的第一个和最后一个索引来进行切片,并得到一个新的列表。依然符合差一行为。
    nums = list(range(1, 11))
    # 实际上是从索引1到4
    print(nums[1:5])  # [2, 3, 4, 5]
    # 没有指定开始索引会默认从0开始  没指定结束索引会默认到列表最后一个元素结束
    print(nums[:5])  # [1, 2, 3, 4, 5]
    print(nums[5:])  # [6, 7, 8, 9, 10]
    print(nums[:])  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    # 也支持负索引
    print(nums[-3:])  # [8, 9, 10]
    
    • 列表的复制:列表的复制可以直接使用切片的方式,不能直接将变量赋值给另一个变量,这和java中的概念(list.addAll)是相同的。
    # 这样相当于将变量nums和nums_2都关联到了同一个列表,不是复制
    nums = [1, 2, 3]
    nums_2 = nums
    nums_2.append(4)
    print(nums_2)  # [1, 2, 3, 4]
    print(nums)  # [1, 2, 3, 4]
    
    # 可以用切片来达到复制列表的目的
    nums = [1, 2, 3]
    nums_2 = nums[:]
    nums_2.append(4)
    print(nums_2)  # [1, 2, 3, 4]
    print(nums)  # [1, 2, 3]
    

    元组

    python将不可修改的值称为不可变的,而不可变的列表称为元组。

    • 元组使用圆括号标识,除了元素不可变之外,可以向操作列表一样遍历、操作元组。
    # 元组:不可变的列表
    nums = (1, 2, 3)
    print(nums)  # (1, 2, 3)
    print(nums[-2:])  # (2, 3)
    

    if语句

    语法同大多数编程语言,仅仅是书写格式不同。

    • 条件判断:
      • 区分大小写,如果不想区分大小写判断是否相等,可以先都转换成小写再判断。
      • 支持==、>、<、>=、<=、!=判断。
      • 多个判断条件可以使用andor关键字,效果等于java中的&&和||。
      • 判断元素是否包含在某个列表中时,可以使用innot in关键字。
      • python在进行条件判断时,会将非空的字符串或列表认为True,反之为False。
    a = "a"
    b = "A"
    if a == b:  # a.lower() == b.lower()
        print("a == b")
    elif a.lower() == b.lower():
        print("a.lower() == b.lower()")
    else:
        print(False)
    
    nums = [1, 2, 3]
    nums_2 = [3, 4, 5]
    if (3 in nums) and (3 not in nums_2):  # False
        print(True)
    else:
        print(False)
    
    nums = []
    a = "a"
    if nums:  # a
        print("nums")
    elif a:
        print("a")
    else:
        print(False)
    

    字典

    在Python中,字典是一系列键--值对 。每个键都与一个值相关联,你可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。类似于java中的Map。

    • python中,字典用花括号来标识,每一个键值对之间以逗号分隔。
    student = {"name": "Allen", "age": 15}
    
    • 可以通过字典的键来访问与之关联的值。
    • 字典是一种动态结构,可随时在其中添加、修改键值对,只需指定字典的键即可。
    • 可以通过del语句删除字典中的键值对。
    student = {"name": "Allen", "age": 15}
    print(student["name"])  # Allen
    student["name"] = "Lili"
    print(student)  # {'name': 'Lili', 'age': 15}
    student["address"] = "ChangSha"
    print(student)  # {'name': 'Lili', 'age': 15, 'address': 'ChangSha'}
    del student["address"]
    print(student)  # {'name': 'Lili', 'age': 15}
    
    • 可以通过for循环遍历字典的所有键、所有值或者是所有的键值对。但是不保证遍历顺序和存储顺序相同。
    student = {'name': 'Lili', 'age': 15, 'address': 'ChangSha'}
    for k, v in student.items():
        print(str(k) + ":" + str(v))
    
    for k in student.keys():  # 遍历字典时会默认遍历key,因此等效于 for k in student:
        print(k)
    
    for v in set(student.values()):  # 如果需要去重的话,可以使用集合set,类似于列表,但每个元素都是独一无二的
        print(v)
    

    while循环

    基本语法同大多数编程语言,仅书写格式不同。

    nums = [1, 1, 1, 1, 2, 2, 1, 3]
    while 1 in nums:
        nums.remove(1)
    print(nums)  # [2, 2, 3]
    

    函数

    • 函数用关键词def定义,函数体依然采用缩进方式。
    • 函数的说明文档用三引号注释,写在函数体的第一行。
    def print_hello():
        """打招呼"""
        print("Hello")
    
    
    print_hello()  # Hello
    
    • 参数传递:python中实参的传递有三种方式:位置实参,关键字实参和默认值。位置实参即基于实参的顺序依次传递,这是大多数编程语言中的一种普遍做法。关键字实参通过键值对的方式传递参数,不用考虑参数的顺序。默认值即在编写函数时为形参指定一个默认值,调用函数时如果不指定实参,则使用此默认值。注意如果不指定默认值,则调用函数时必须传入该实参。
    def print_hello(name, age="15"):
        """打招呼"""
        print("你好,我叫" + str(name) + "," + str(age) + "岁")
    
    
    print_hello("李狗蛋", "12")  # 你好,我叫李狗蛋,12岁
    print_hello("12", "李狗蛋")  # 你好,我叫12,李狗蛋岁
    print_hello(age="12", name="李狗蛋")  # 你好,我叫李狗蛋,12岁
    # 形参可以有默认值,相当于简化了java中的方法的多态
    print_hello("李狗蛋")  # 你好,我叫李狗蛋,15岁
    
    • 返回值:python中函数可以通过关键字return返回一个值,且python是弱类型语言,无需指定返回的值的类型。
    • 列表作为实参传入时,如果函数内部对该列表做了修改,则原列表也会改变,这一点同java是一样的。如果不想修改原列表,可以将列表的一个副本作为实参传入,比如使用切片。
    def getList(list):
        list[0] = 2
        return list
    
    
    a = [1, 2]
    print(getList(a))  # [2, 2]
    print(a)  # [2, 2]
    a = [1, 2]
    print(getList(a[:]))  # [2, 2]
    print(a)  # [1, 2]
    
    • 函数可以使用 *+形参名 的形式添加任意数量的参数(相当于在函数内部,将可变参数组成了一个tuple),类似于java中的 形参名+... 符号,如果有多个不同类型的形参,这种接收任意数量参数的形参只能放在最后。
    def muti(*name):  # 形参名*name 中的星号让Python创建一个名为name 的空元组,并将收到的所有值都封装到这个元组中。
        print(name)
    
    
    muti("a")  # ('a',)
    muti("a", "b", "c")  # ('a', 'b', 'c')
    
    • 函数可以通过两个星号来接收任意数量的关键字实参(键值对,相当于在函数内部,将可变关键字参数组成了一个dict)。
    def person(name, age, **other):  # 形参名**other 中的星号让Python创建一个名为other 的空字典,并将收到的所有键值对都封装到这个字典中。
        p = {"name": name, "age": age}
        for k, v in other.items():
            p[k] = v
        print(other)
    
    
    person("Allen", 15, sex="man", address="ChangSha")  # {'name': 'Allen', 'age': 15, 'sex': 'man', 'address': 'ChangSha'}
    

    如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和score作为关键字参数。这种方式定义的函数如下:

    def person(name, age, *, address, score):
        print(name, age, address, score)
    
    person("Allen", 15, address='Beijing', score=98)
    

    和关键字参数 ** other不同,命名关键字参数需要一个特殊分隔符* ,*后面的参数被视为命名关键字参数。

    • 在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
    • 导入外部函数:要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。导入方式:
      • import module_name:导入整个模块。
      • import module_name as other_name:为导入的模块起一个别名。
      • from module_name import function_name:导入模块中的某个函数,function_name可以有多个,用逗号隔开,表示导入该模块的多个函数。
      • from module_name import function_name as other_name:导入模块中的某个函数,并起一个别名,一般原函数名字太长或者有同名函数时使用。
      • from module_name import *:导入该模块的全部函数。
        注:只导入模块时,需通过module_name.function_name调用(前两种方式),导入函数时,可以直接通过函数名使用(后三种方式)。当然,有别名的情况下也可以使用别名。

    • 通过关键字class标识,类名的首字母大写,采用驼峰命名法,可以在类名的下一行添加注释文档,用三引号标识。
    • python的类有一个特殊的方法__ init__(),每次创建类的实例时都会运行这个方法,类似于java中的构造函数。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
    • 形参self必不可少,还必须位于其他形参的前面。每个与类相关联的方法调用都自动传递实参self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
    • 以self 为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量,我们可以将这些以self为前缀的变量称为属性。
    • 以两个下划线开头可以定义类的私有方法和属性,命名格式为__private_method,self.__private_attrs。
    class Person:
        """测试类"""
        def __init__(self, name="Allen", age=15, sex="man"):
            self.name = name
            self.age = age
            self.sex = sex
            self.address = ""
            print("person " + name + " init")
    
        def walk(self):
            print(self.name + " can walk.")
    
        def run(self):
            self.walk()
            print(self.name + " can run too.")
    
    • 继承。
    class Person:
        """测试类"""
    
        def __init__(self, name, age=15, sex="man"):
            self.name = name
            self.age = age
            self.sex = sex
            self.address = ""
            print("person " + name + " init")
    
        def walk(self):
            print(self.name + " can walk.")
    
        def run(self):
            self.walk()
            print(self.name + " can run too.")
    
    
    person = Person("Allen")  # person Allen init
    person.run()  # Allen can walk.  Allen can run too.
    
    
    class Student(Person):  # Student继承于Person
        def __init__(self, name):  # 子类的__init__方法需要接收父类的所有参数,有默认值的可以不传,会取默认值
            super().__init__(name)  # 子类继承父类的所有属性和方法
    
        def walk(self):  # 重写父类方法
            print("override function.")
    
        def get_teacher(self, teacher_name):  # 子类的自定义方法
            print(self.name + "'s teacher is " + teacher_name)
    
    
    student = Student("Allen")  # person Allen init
    student.get_teacher("Lili")  # Allen's teacher is Lili
    student.walk()  # override function.
    

    文件读写

    通过open函数打开一个文件,进行读写操作,完成后通过close函数关闭文件,也可以使用with关键字,让python自己选择适时关闭文件。

    def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
    

    open函数可以接收一个mode参数,包括以下值:

    • 'r' 只读方式打开 (default)
    • 'w' 只写方式打开,打开文件会清空文件,再写入,文件不存在时会自动创建文件。
    • 'x' 创建一个新文件并以只写方式打开
    • 'a' 只写方式打开,打开文件会将写入内容拼接到文件最后,
    • 'b' 字节模式
    • 't' 文本模式(default)
    • '+' 打开一个硬盘文件进行更新 (reading and writing)
    • 'U' universal newline mode (已过时)

    默认模式为"rt"。

    读文件

    测试文件 file_io_test:

    abcdefg
    hijklmn
    opq
    rst
    uvw
    xyz
    
    • 读取整个文件
    with open("file_io_test") as file:  # 关键字with 在不再需要访问文件后适时将其关闭。
        print(file.read())  # read()可以接收一个int参数,表示读取的字节数,传-1表示读取全部,默认值为-1
    
    • 读取一行
    with open("file_io_test") as file:
        print(file.readline())  # abcdefg 行末尾有一个换行符
        print(file.readline())  # hijklmn
    
    • 读取每行,并存储到一个列表
    with open("file_io_test") as file:
        print(file.readlines())  # ['abcdefg\n', 'hijklmn\n', 'opq\n', 'rst\n', 'uvw\n', 'xyz']
    
    • 逐行读取
    with open("file_io_test") as file:
        for line in file:  # 等同于line = file.readline()
            print(line)
    
    • 是否可读
    with open("file_io_test") as file:
        print(file.readable())  # readable()是否可读,返回一个布尔值
    

    写文件

    with open("file_write_test", mode="w+") as file:  # w换成a后可以附加到文件中,不会覆盖
        file.write("456")  # 写入456
        print(file.readable())  # True
    

    异常

    处理异常:

    def divide(a, b):
        """除法运算"""
        try:
            result = a / b
        except ZeroDivisionError:
            print("除数不能为0")
        else:
            print(result)
        finally:
            print("运行完毕")
    
    
    divide(1, 0)  # 除数不能为0  运行完毕
    divide(1, 5)  # 0.2  运行完毕
    

    存储数据

    通过json存储

    import json
    
    nums = [1, 2, 3, 4, 5]
    with open("jsonTest.json", "w") as file:
        json.dump(nums, file)  # 写入文件,接收一个内容对象和文件对象
    
    with open("jsonTest.json") as file:
        result = json.load(file)
        print(result)
    

    你可能感兴趣的:(一个java程序员的python之旅----初识)