我爱编程

1.Python语法

2018-05-15  本文已影响97人  南风nanfeng

一、变量变量的命令和使用(2018-04-26)


二、字符串


三、数字


age = 23
message = "Happy " + age + "rd Birthday!"
print(message)

代码报错:

Traceback (most recent call last):
File "birthday.py", line 2, in <module>
message = "Happy " + age + "rd Birthday!"
❶ TypeError: Can't convert 'int' object to str implicitly

这是一个类型错误 , 意味着Python无法识别你使用的信息。 在这个示例中, Python发现你使用了一个值为整数(int ) 的变量, 但它不知道该如何解读这个值(见❶) 。 Python知道, 这个变量表示的可能是数值23, 也可能是字符2和3。 像上面这样在字符串中使用整数时, 需要显式地指出你希望Python将这个整数用作字符串。 为此, 可调用函数str() ,它让Python将非字符串值表示为字符串:

age = 23
message = "Happy " + str(age) + "rd Birthday!"
print(message)

>>> python2.7
>>> 3 / 2
1

Python返回的结果为1, 而不是1.5。 在Python 2中, 整数除法的结果只包含整数部分, 小数部分被删除。 请注意, 计算整数结果时, 采取的方式不是四舍五入, 而是将小数部分直接删除。


四、Python之禅

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

五、列表

5.1 列表特征


5.2组织列表


5.3遍历整个列表

magicians = ['alice', 'david', 'carolina']
for ma in magicians:
    print(ma.title() + ", that was a great trick!");
    print("I can't wait to see your next trick, " + ma.title() + ".\n")
print("Thank you, everyone. That was a great magic show!");


5.4列表解析

print([value ** 2 for value in range(1,11)]);

5.5列表的部分元素-切片

players = ['charles', 'martina', 'michael', 'florence', 'eli'];
print(players[0:3]);


5.6原组


六、Py格式设置


七、if语句

-要判断两个值是否不等, 可结合使用惊叹号和等号(!= ) , 其中的惊叹号表示不 , 在很多编程语言中都如此。

八、字典

九、用户输入和while循环

9.1 用户输入input()


十、函数

关键字def 来告诉Python你要定义一个函数。文档字符串用三引号括起, Python使用它们来生成有关程序中函数的文档。下面介绍参数传递,主要有三种种方式,第一、位置实参;第二、关键字实参;第三、默认值形参。
10.1 位置实参
使用位置实参来调用函数时, 如果实参的顺序不正确, 结果可能出乎意料。
10.2 关键字实参
关键字实参 是传递给函数的名称—值对。 你直接在实参中将名称和值关联起来了, 因此向函数传递实参时不会混淆(不会得到名为Hamster的harry这样的结果) 。 关键字实参让你无需考虑函数调用中的实参顺序, 还清楚地指出了函数调用中各个值的用途。
10.2 默认值
编写函数时, 可给每个形参指定默认值 。 在调用函数中给形参提供了实参时, Python将使用指定的实参值; 否则, 将使用形参的默认值。 因此, 给形参指定默认值后, 可在函数调用中省略相应的实参。 使用默认值可简化函数调用, 还可清楚地指出函数的典型用法。
使用默认值时, 在形参列表中必须先列出没有默认值的形参, 再列出有默认值的实参。 这让Python依然能够正确地解读位置实参。
10.3 传递任意数量的实参
有时候, 你预先不知道函数需要接受多少个实参, 好在Python允许函数从调用语句中收集任意数量的实参。例如, 来看一个制作比萨的函数, 它需要接受很多配料, 但你无法预先确定顾客要多少种配料。 下面的函数只有一个形参*toppings , 但不管调用语句提供了多少实参, 这个形参都将它们统统收入囊中。

def make_pizza(*toppings):
    print(toppings);
    
make_pizza('mushrooms', 'green peppers', 'extra cheese')

形参名*toppings 中的星号让Python创建一个名为toppings 的空元组, 并将收到的所有值都封装到这个元组中。 函数体内的print 语句通过生成输出来证明Python能够处理使用一个值调用函数的情形, 也能处理使用三个值来调用函数的情形。
如果要让函数接受不同类型的实参, 必须在函数定义中将接纳任意数量实参的形参放在最后。 Python先匹配位置实参和关键字实参, 再将余下的实参都收集到最后一个形参中。

10.4 导入整个模块
要让函数是可导入的, 得先创建模块。 模块 是扩展名为.py的文件, 包含要导入到程序中的代码。
你还可以导入模块中的特定函数, 这种导入方法的语法如下:

from module_name import function_name

通过用逗号分隔函数名, 可根据需要从模块中导入任意数量的函数:

from module_name import function_name1, function_name2

若使用这种语法, 调用函数时就无需使用句点。 由于我们在import 语句中显式地导入了函数make_pizza() , 因此调用它时只需指定其名称。

10.5 使用as给函数指定别名
如果要导入的函数的名称可能与程序中现有的名称冲突, 或者函数的名称太长, 可指定简短而独一无二的别名 ——函数的另一个名称, 类似于外号。 要给函数指定这种特殊外号, 需要在导入它时这样做。

10.6 导入模块中所有函数
使用星号(* ) 运算符可让Python导入模块中的所有函数:

from module_name import *

10.6 函数编写指南
编写函数时, 需要牢记几个细节。 应给函数指定描述性名称, 且只在其中使用小写字母和下划线。 描述性名称可帮助你和别人明白代码想要做什么。 给模块命名时也应遵循上述约定。
每个函数都应包含简要地阐述其功能的注释, 该注释应紧跟在函数定义后面, 并采用文档字符串格式。 文档良好的函数让其他程序员只需阅读文档字符串中的描述就能够使用它: 他们完全可以相信代码如描述的那样运行; 只要知道函数的名称、 需要的实参以及返回值的类型, 就能在自己的程序中使用它。
给形参指定默认值时, 等号两边不要有空格:

def function_name(parameter_0, parameter_1='default value')

所有的import 语句都应放在文件开头, 唯一例外的情形是, 在文件开头使用了注释来描述整个程序。

十一、类

根据约定, 在Python中, 首字母大写的名称指的是类。 这个类定义中的括号是空的, 因为我们要从空白创建这个类。

class Dog():
    def __init__(self, name, age):
        self.name = name;
        self.age = age;
        
    def sit(self):
        print(self.name.title() + ' is now sitting.');
        
    def roll_over(self):
        print(self.name.title() + ' rolled over.');

11.1 方法__init__()
方法__init__() 是一个特殊的方法, 每当你根据Dog 类创建新实例时, Python都会自动运行它。 在这个方法的名称中, 开头和末尾各有两个下划线, 这是一种约定, 旨在避免Python默认方法与普通方法发生名称冲突。
在这个方法的定义中, 形参self 必不可少, 还必须位于其他形参的前面。 为何必须在方法定义中包含形参self 呢? 因为Python调用这个__init__() 方法来创建Dog 实例时, 将自动传入实参self 。 每个与类相关联的方法调用都自动传递实参self , 它是一个指向实例本身的引用, 让实例能够访问类中的属性和方法。
11.2 继承
子类继承了其父类的所有属性和方法, 同时还可以定义自己的属性和方法。
创建子类的实例时, Python首先需要完成的任务是给父类的所有属性赋值。 为此, 子类的方法__init__() 需要父类施以援手。

class Car():
   def __init__(self, make, model, year):
       self.make = make;
       self.model = model;
       self.year = year;
       self.odometer_reading = 0;
       
   def read_odometer(self):
       print("This car has " + str(self.odometer_reading) + " miles on it.")

   def update_odometer(self, mill):
       if mill >= self.odometer_reading:
           self.odometer_reading = mill
       else:
           print('U cannot roll back.');

   def get_description_name(self):
       long_name = str(self.year) + ' ' + self.make + ' ' + self.model
       return long_name.title();
       
       
class ElectricCar(Car):
   def __init__(self, make, model, year):
       super().__init__(make, model, year)

首先是Car 类的代码 。 创建子类时, 父类必须包含在当前文件中, 且位于子类前面。 我们定义了子类ElectricCar 。 定义子类时, 必须在括号内指定父类的名称。 方法init() 接受创建Car 实例所需的信息 。
super() 是一个特殊函数, 帮助Python将父类和子类关联起来。 这行代码让Python调用ElectricCar 的父类的方法init() , 让ElectricCar 实例包含父类的所有属性。 父类也称为超类 (superclass) , 名称super因此而得名。

11.3 重写父类的方法
对于父类的方法, 只要它不符合子类模拟的实物的行为, 都可对其进行重写。 为此, 可在子类中定义一个这样的方法, 即它与要重写的父类方法同名。 这样, Python将不会考虑这个父类方法, 而只关注你在子类中定义的相应方法。

11.4 导入类
随着你不断地给类添加功能, 文件可能变得很长, 即便你妥善地使用了继承亦如此。 为遵循Python的总体理念, 应让文件尽可能整洁。 为在这方面提供帮助, Python允许你将类存储在模块中, 然后在主程序中导入所需的模块。

from car import Car
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())

import 语句让Python打开模块car , 并导入其中的Car 类。 这样我们就可以使用Car 类了, 就像它是在这个文件中定义的一样。

可根据需要在程序文件中导入任意数量的类。 如果我们要在同一个程序中创建普通汽车和电动汽车, 就需要将Car 和ElectricCar 类都导入:

from car import Car, ElectricCar

11.5 导入整个模块
你还可以导入整个模块, 再使用句点表示法访问需要的类。 这种导入方法很简单, 代码也易于阅读。 由于创建类实例的代码都包含模块名, 因此不会与当前文件使用的任何名称发生冲突。下面的代码导入整个car 模块, 并创建一辆普通汽车和一辆电动汽车:

import car
my_beetle = car.Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = car.ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())

我们导入了整个car 模块。 接下来, 我们使用语法 module_name.class_name 访问需要的类。

11.6 导入模块中的所有类
要导入模块中的每个类, 可使用下面的语法:

from module_name import *

不推荐使用这种导入方式, 其原因有二。 首先, 如果只要看一下文件开头的import 语句, 就能清楚地知道程序使用了哪些类, 将大有裨益; 但这种导入方式没有明确地指出你使用了模块中的哪些类。 这种导入方式还可能引发名称方面的困惑。 如果你不小心导入了一个与程序文件中其他东西同名的类, 将引发难以诊断的错误。 这里之所以介绍这种导入方式, 是因为虽然不推荐使用这种方式, 但你可能会在别人编写的代码中见到它。

11.7 编码风格
类名应采用驼峰命名法 , 即将类名中的每个单词的首字母都大写, 而不使用下划线。 实例名和模块名都采用小写格式, 并在单词之间加上下划线。
可使用空行来组织代码, 但不要滥用。 在类中, 可使用一个空行来分隔方法; 而在模块中, 可使用两个空行来分隔类。
需要同时导入标准库中的模块和你编写的模块时, 先编写导入标准库模块的import 语句, 再添加一个空行, 然后编写导入你自己编写的模块的import 语句。 在包含多条import 语句的程序中, 这种做法让人更容易明白程序使用的各个模块都来自何方。

十二、文件和异常

下面的程序打开并读取这个文件, 再将其内容显示到屏幕上:

with open('pi_digits.txt') as file_object:
    content = file_object.read()
    print(content)

在这个程序中, 第1行代码做了大量的工作。 我们先来看看函数open() 。 要以任何方式使用文件——哪怕仅仅是打印其内容, 都得先打开 文件, 这样才能访问它。 函数open()接受一个参数: 要打开的文件的名称。 Python在当前执行的文件所在的目录中查找指定的文件。

12.1 关键字with 在不再需要访问文件后将其关闭。 在这个程序中, 注意到我们调用了open() , 但没有调用close() ; 你也可以调用open() 和close() 来打开和关闭文件, 但这样做时, 如果程序存在bug, 导致close() 语句未执行, 文件将不会关闭。 这看似微不足道, 但未妥善地关闭文件可能会导致数据丢失或受损。 如果在程序中过早地调用close() , 你会发现需要使用文件时它已关闭 (无法访问) , 这会导致更多的错误。 并非在任何情况下都能轻松确定关闭文件的恰当时机, 但通过使用前面所示的结构, 可让Python去确定: 你只管打开文件, 并在需要时使用它, Python自会在合适的时候自动将其关闭。

12.2 创建一个包含文件各行内容的列表
使用关键字with 时, open() 返回的文件对象只在with 代码块内可用。 如果要在with 代码块外访问文件的内容, 可在with 代码块内将文件的各行存储在一个列表中, 并在with 代码块外使用该列表: 你可以立即处理文件的各个部分, 也可推迟到程序后面再处理。

with open('pi_digits.txt') as file_object:
    lines = file_object.readlines()
for line in lines:
    print(line);

文件对象file_object读取多行文件存储到数组lines中,在with代码块外,依然能够引用该数组,这个例子告诉我们,Python没有块级变量、局部变量。

12.3 写入文件
要将文本写入文件, 你在调用open() 时需要提供另一个实参, 告诉Python你要写入打开的文件。 为明白其中的工作原理, 我们来将一条简单的消息存储到文件中, 而不是将其打印到屏幕上:

filename = 'programming.txt'
with open(filename, 'w') as file_object:
    file_object.write('I love programming.');

在这个示例中, 调用open() 时提供了两个实参。 第一个实参也是要打开的文件的名称; 第二个实参('w' ) 告诉Python, 我们要以写入模式 打开这个文件。 打开文件时, 可指定读取模式 ('r' ) 、 写入模式 ('w' ) 、 附加模式 ('a' ) 或让你能够读取和写入文件的模式('r+' ) 。 如果你省略了模式实参, Python将以默认的只读模式打开文件。

12.4 异常
Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。 每当发生让Python不知所措的错误时, 它都会创建一个异常对象。 如果你编写了处理该异常的代码, 程序将继续运行; 如果你未对异常进行处理, 程序将停止, 并显示一个traceback, 其中包含有关异常的报告。

异常是使用try-except 代码块处理的。 try-except 代码块让Python执行指定的操作, 同时告诉Python发生异常时怎么办。 使用了try-except 代码块时, 即便出现异常,程序也将继续运行: 显示你编写的友好的错误消息, 而不是令用户。

print(1/0)
Traceback (most recent call last):
  File "division.py", line 1, in <module>
    print(1/0)
ZeroDivisionError: division by zero

在上述traceback中,ZeroDivisionError 是一个异常对象。 Python无法按你的要求做时, 就会创建这种对象。 在这种情况下, Python将停止运行程序, 并指出引发了哪种异常, 而我们可根据这些信息对程序进行修改。 下面我们将告诉Python, 发生这种错误时怎么办; 这样, 如果再次发生这样的错误, 我们就有备无患了。

try:
    print(1/0)
except ZeroDivisionError:
    print('u can not divide by zero!');
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")

while True:
    first_num = input('\nFirst Number:')
    if first_num=='q':
        break;
    second_num = input('\nSecond Number:')
    if second_num=='q':
        break;
    try:
        answer = int(first_num) / int(second_num)
    except ZeroDivisionError:
        print('u can not divide by zero!');
    else:
        print(answer)
filename = 'alice'
try:
    with open(filename) as file_obj:
        contents = file_obj.read()
except FileNotFoundError:
    print('Sorry, the file "' + filename + '" is not exist.')
filename = 'alice'
try:
    with open(filename) as file_obj:
        contents = file_obj.read()
except FileNotFoundError:
    pass

测试代码

Python在unittest.TestCase 类中提供了很多断言方法。 前面说过, 断言方法检查你认为应该满足的条件是否确实满足。 如果该条件确实满足, 你对程序行为的假设就得到了确认, 你就可以确信其中没有错误。 如果你认为应该满足的条件实际上并不满足, Python将引发异常。

上一篇 下一篇

猜你喜欢

热点阅读