一个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<Object>。
  • 有序集合,因此支持按索引访问,索引从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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容