跟我一起学python(一)
这是“跟我一起学Python”的第一章,也是跟大家一起交流python的开端。python是一门相对而言比较简单的语言,尤其在机器学习领域应用很广泛。我是一名多年的Java开发人员,这次学习python,目的也是想涉足机器学习领域。
我的学习来源是来自草根学python,在学习过程中我也融合了多年的Java研发经验,在知识点上做了补充,同时对里面的代码样例也结合Java,认真地进行编码测试,非常适合Python初学者学习研究。
语法规则
解释型or编译型
Python究竟是解释型语言还是编译型语言?比如C就是显著的编译型语言,将C语言编译为机器能够识别的机器码;Java也是编译型语言,通过编译器编译为JVM能够处理的字节码。但是Python究竟是解释型还是编译型呢?从外表看,python更像是解释型语言,因为它有很多解释型语言的特性,我们感受不到它的编译过程,这和Java不同,Java是需要手动编译为.class文件的,而python就是执行.py文件,所以我们更多地称之为解释型语言。
但是事实上,python也是需要编译的,它需要先编译为字节码,然后再执行。及时在作为交互式命令行场景下,它也是先编译为字节码再执行。
我们通常所说的python其实是CPython,CPython是一个基于C语言编写的解释器,这也是默认的解释器,python在经过CPython编译为字节码后,交给CPython虚拟机运行。当然既然有C语言编写的解释器,那有没有其他语言编写的解释器呢?当然有,比如基于Java的解释器Jython,Jython生成可以在JVM上执行的java字节码。
语法规则
Python语法对大小写敏感,采用缩进方式,冒号:
结尾后缩进表示代码块。
# 判断一个数是否是正整数
a=100
if a>=0:
print("yes")
else:
print("no")
字符串编码
对于正常编码而言,我们通常使用UTF-8。为了让Python解释器能够按照UTF-8编码读取源代码,我们需要对代码做一些处理。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
- 第一行注释是为了告诉 Linux/OS X 系统,这是一个 Python 可执行程序,Windows 系统会忽略这个注释;
- 第二行注释是为了告诉 Python 解释器,按照 UTF-8 编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
申明了 UTF-8 编码并不意味着你的 .py 文件就是 UTF-8 编码的,必须并且要确保文本编辑器正在使用 UTF-8 without BOM 编码。
变量
Python的变量名必须是英文、数字和_
的组合,并且不能使用数字开头。
# 正确
username = "张三"
user_password = "123456"
# 错误
1username = "张三"
user@password = "123456"
Python是一种动态语言,定义变量不需要申明数据类型,因此可以将任意值赋值给同一个变量
a = 100
print(a)
a = "张三"
print(a)
多个变量赋值
- 情况一
# a\b\c都等于1
a = b = c = 1;
- 情况二
# a=1;b=2;c="hello world"
a,b,c = 1,2,"hello world"
值传递or引用传递
- 值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。
- 引用传递:也称地址传递,在方法调用时,实际上是把参数的引用(传的是地址,而不是参数的值)传递给方法中对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
在Python中,数字、字符或者元组等不可变对象类型都属于值传递,而字典dict或者列表list等可变对象类型属于引用传递。
# 测试数字传递类型
def numRef(arg):
arg=20
print("arg="+str(arg)) # arg=20
a = 10
numRef(10)
print("a="+str(a)) # a=10,说明是值传递
# 测试字符串传递类型
def stringRef(arg):
arg = arg+"123"
print("arg="+arg) # arg=hello world!123
a = "hello world!"
stringRef(a)
print("a="+str(a)) # a=hello world!,说明是值传递
# 测试List
def listRef(arg):
arg.append("王二")
print("arg="+str(arg)) # arg=['张三', '李四', '王二']
a = ["张三","李四"]
listRef(a)
print("a="+str(a)) #a=['张三', '李四', '王二'],说明是引用传递
# 测试Tuple
def tupleRef(arg):
arg = (123,456)
print("arg="+str(arg)) # arg=(123, 456)
a = ("张三","李四")
tupleRef(a)
print("a="+str(a)) # a=('张三', '李四'),说明是值传递
如果不想修改List的值,可以使用copy模块。
深拷贝and浅拷贝
上面提到值传递以及引用传递,这一章节谈谈最后提到的不想方法修改list的值,可以使用copy模块。copy包括浅拷贝和深拷贝。
- 浅拷贝:对第一层list做拷贝,使用
copy.copy()
方法; - 深拷贝:对所有元素和子元素做拷贝,使用
copy.deepcopy()
方法。
import copy
users=[["张三","李四"],123,456]
users1 = copy.copy(users)
users2 = copy.deepcopy(users)
users1[0].append("王二")
users2[0].append("唐一")
print("原列表users="+str(users))
print("浅拷贝users1="+str(users1))
print("深拷贝users2="+str(users2))
结果:
原列表users=[['张三', '李四', '王二'], 123, 456]
浅拷贝users1=[['张三', '李四', '王二'], 123, 456]
深拷贝users2=[['张三', '李四', '唐一'], 123, 456]
命名规范和注释
命名规范
模块名
模块名尽量使用小写命名,首字母保持小写,尽量不要使用下划线(如果多个单词,可是使用下划线)
# 正确写法
import media
import user_login
# 不推荐写法
import Media
类名
类名使用驼峰命名风格,首字母大写。
私有类可以使用_
开头
# 正确写法
class User():
pass
class Boy(User):
pass
class _PrivateUser(User):
pass
函数名
函数名一律小写,如果有多个单词,用_
隔开。
def login():
def login_with_password():
私有函数在前面加_
class User():
def _private_login():
pass
变量名
- 变量名尽量小写,多个单词用
_
隔开
if _password_ == '123456':
login_success = 1
- 常量全部大写,多个单词用
_
隔开
DEFAULT_PATH = 'index.html'
注释
块注释
#
后空一格,段落间用#
开头的空行隔开
# 块注释
# 块注释
#
# 块注释
行注释
注释同样使用#
后加一格空格,填写注释信息。
行注释与代码行之间至少空两格。
sum = sum + 1 # 求和
文档注释(Docstring)
作为文档的Docstring一般出现在模块头部、函数和类的头部,这样在python中可以通过对象的__doc__
对象获取文档. 编辑器和IDE也可以根据Docstring给出自动提示。
-
文档注释以 “”" 开头和结尾, 首行不换行, 如有多行, 末行必需换行, 以下是Google的docstring风格示例
# -*- coding: utf-8 -*- """Example docstrings. This module demonstrates documentation as specified by the `Google Python Style Guide`_. Docstrings may extend over multiple lines. Sections are created with a section header and a colon followed by a block of indented text. Example: Examples can be given using either the ``Example`` or ``Examples`` sections. Sections support any reStructuredText formatting, including literal blocks:: $ python example_google.py Section breaks are created by resuming unindented text. Section breaks are also implicitly created anytime a new section starts. """
-
不要在文档注释复制函数定义原型, 而是具体描述其具体内容, 解释具体参数和返回值等
# 不推荐的写法(不要写函数原型等废话) def function(a, b): """function(a, b) -> list""" ... ... # 正确的写法 def function(a, b): """计算并返回a到b范围内数据的平均值""" ... ...
-
对函数参数、返回值等的说明采用numpy标准, 如下所示
def func(arg1, arg2): """在这里写函数的一句话总结(如: 计算平均值). 这里是具体描述. 参数 ---------- arg1 : int arg1的具体描述 arg2 : int arg2的具体描述 返回值 ------- int 返回值的具体描述 参看 -------- otherfunc : 其它关联函数等... 示例 -------- 示例使用doctest格式, 在`>>>`后的代码可以被文档测试工具作为测试用例自动运行 >>> a=[1,2,3] >>> print [x + 3 for x in a] [4, 5, 6] """
-
文档注释不限于中英文, 但不要中英文混用
-
文档注释不是越长越好, 通常一两句话能把情况说清楚即可
-
模块、公有类、公有方法, 能写文档注释的, 应该尽量写文档注释.
参考内容:草根学Python