《Python修炼》学习--待学习

虚拟环境安装

示例:

>>> print(3, [1,2,3], {'name':'David'}) # 一次可以打印多个对象,对象可以是任意类型
3 [1, 2, 3] {'name': 'David'}
>>> print(1, 2, 'x','y', sep='*') # 多个打印对象之间使用星号分隔
1*2*x*y
>>> for item in [1, 2, 'x','y']:
        print(item, end=',') # 不换行打印

1,2,x,y,
>>> with open(r'd:\print_out.txt', 'w') as fp: # 打印到文件d:\print_out.txt
        print(1, 2, 'x','y', sep='*', file=fp)
        
        
        
# -*- coding: utf-8 -*-
import time
def printer(text, delay=0.2):
    """打字机效果"""

    for ch in text:
        print(ch, end='', flush=True)
        time.sleep(delay)
    print()
        def waiting(cycle=20, delay=0.1):
    """旋转式进度指示"""
    for i in range(cycle):
        for ch in ['-', '\\', '|', '/']:
            print('\b%s'%ch, end='', flush=True)
            time.sleep(delay)
    print()
        def cover(cycle=100, delay=0.2):
    """覆盖式打印效果"""

    for i in range(cycle):
        s = '\r%d'%i
        print(s.ljust(3), end='', flush=True)
        time.sleep(delay)
    print()
        if __name__ == '__main__':
    printer('玄铁重剑,是金庸小说笔下第一神剑,持之则无敌于天下。')
    waiting(cycle=20)
    cover(cycle=20)

6

.常用格式化符号

%常用格式化符号

7、文件读写

>>> data = [[0.468,0.975,0.446],[0.718,0.826,0.359]]
>>> with open(r'd:\csv_data.csv', 'w') as fp: # 写入csv文件
        for line in data:
            ok = fp.write('%s\n'%','.join([str(item) for item in line]))

>>> result = list()
>>> with open(r'd:\csv_data.csv', 'r') as fp: # 读出csv文件并解析
        for line in fp.readlines():
            result.append([float(f) for f in line.strip().split(',')])

>>> result
[[0.468, 0.975, 0.446], [0.718, 0.826, 0.359]]

8、

> type(5)
<class 'int'>
>>> type('ssdf')
<class 'str'>
>>> type([])
<class 'list'>
>>> type(print)
<class 'builtin_function_or_method'>
>>> type(range(5))
<class 'range'>


>> a = [3,4,5]
>>> b = ('x', 'y')
>>> c = dict()
>>> d = 'python'
>>> isinstance(a, list)
True
>>> isinstance(b, list)
False
>>> isinstance(c, (dict,str))
True
>>> isinstance(d, (dict,str))
True
>>> isinstance(b, (dict,str))
False

9、

enumerate()
>> for index, item in enumerate([True, False, None]):
        print(index, item, sep='->')

0->True
1->False
2->None
>>> for index, item in enumerate('xyz'):
        print(index, item, sep='->')

0->x
1->y
2->z
zip()
>>> a = ['x','y','z']
>>> b = [3,4,5]
>>> for k, v in zip(a,b):
        print(k, v, sep='->')

x->3
y->4
z->5
map()
>>> def extract(x): # 开3次方
        return pow(x, 1/3)

>>> result = map(extract, [7,8,9]) #  extract()函数对列表元素逐一运算,返回迭代对象
>>> list(result) # 将迭代对象转为list
[1.912931182772389, 2.0, 2.080083823051904]
>>> list(map(lambda x:pow(x, 1/3), [7,8,9])) # 使用lambda匿名函数更简洁
[1.912931182772389, 2.0, 2.080083823051904]

10、

>>> sum([3,4,5])
12
>>> min(3,4,5), max(3,4,5) # min()/max()函数可以接受多个参数
(3, 5)
>>> min([3,4,5]), max((3,4,5)) # min()/max()函数也可以接受列表或元组作参数
(3, 5)
>>> abs(-3.14)
>>> pow(2,3) # 计算2的3次方
8
>>> pow(2,1/2) # 开平方
1.4142135623730951
>>> divmod(5,2) # 以元组形式返回5/2的商和余数。这在某些场合用起来非常高效、优雅
(2, 1)
>>> round(3.1415926) # 取整
3
>>> round(3.1415926,5) # 精确到小数点后5位
3.14159

二、进阶语法

2、

Python的内置类Exception预定义了18类、50余种错误和警告类型,其中语法错误(SyntaxError)、模块导入错误(ImportError)、类型错误(TypeError)、索引错误(IndexError)、键错误(KeyError)、缩进错误(IndentationError)等都是最常见的错误类型。

若程序在运行过程中发生了Exception预定义的错误,程序的执行过程就会发生改变,抛出Exception异常对象,进入异常处理。如果Exception异常对象没有被捕获,程序就会执行回溯(Traceback)来终止程序。除了程序运行抛出异常,还可以使用raise关键字来触发异常。
>>> def try_error(n=0):
        try:
            if n == 0:
                raise Warning('这是警告信息')
            if n == 1:
                raise SyntaxError('这是语法错误')
            if n == 2:
                raise IndentationError('这是缩进错误')
            if n == 3:
                raise FileNotFoundError('请求不存在的文件或目录')
        except Warning as e:
            print(e)
        except (SyntaxError, IndentationError) as e:
            print(e)
        except FileNotFoundError as e:
            print(e)
        finally:
            print('善后工作')

>>> try_error()
这是警告信息
善后工作
>>> try_error(1)
这是语法错误
善后工作
>>> try_error(2)
这是缩进错误
善后工作
>>> try_error(3)
请求不存在的文件或目录
善后工作

3、

>>> y = 5
>>> print('y是一个负数' if y < 0 else 'y是一个非负数')
y是一个非负数
三元表达式也常用来赋值,举例如下。
>>> y = 5
>>> x = -1 if y < 0 else 1
>>> x
1

4、

>>> a = [1, 2, 3, 4, 5]
>>> result = list()
>>> for i in a:
        result.append(i*i)

>>> result
[1, 4, 9, 16, 25]
如果使用列表推导式,看起来就简洁多了,代码如下。
>>> a = [1, 2, 3, 4, 5]
>>> [i*i for i in a]
[1, 4, 9, 16, 25]
列表推导式还可以配合条件语句,实现更复杂的功能。不过请注意,如果条件只有if,必须放在for循环之后。如果条件类似于三元表达式,则必须置于for循环之前。
>>> [i for i in range(10) if i%2==0]
[0, 2, 4, 6, 8]
>>> [i if i%2==0 else -1*i for i in range(10)]
[0, -1, 2, -3, 4, -5, 6, -7, 8, -9]

5、

断言就是声明表达式的布尔值必须为真的判定,否则将触发AssertionError异常。严格来讲,assert是调试手段,不宜使用在生产环境中,但这不影响用断言来实现一些特定功能,如输入参数的格式、类型验证等。

> def i_want_to_sleep(delay):
        assert(isinstance(delay, (int,float))), '函数参数必须为整数或浮点数'
        print('开始睡觉')
        time.sleep(delay)
        print('睡醒了')

>>> i_want_to_sleep(1.1)
开始睡觉
睡醒了
>>> i_want_to_sleep(2)
开始睡觉
睡醒了
>>> i_want_to_sleep('2')
Traceback (most recent call last):
  File "<pyshell#247>", line 1, in <module>
    i_want_to_sleep('2')
  File "<pyshell#244>", line 2, in i_want_to_sleep
    assert(isinstance(delay, (int,float))), '函数参数必须为整数或浮点数'
AssertionError: 函数参数必须为整数或浮点数

6、

fp = open('data.txt', 'r')
try:
    contents = fp.readlines()
finally:
    fp.close()
如果使用 with-as语法结构,那就“优雅”多了。
>>> with open('data.txt', 'r') as fp:
        contents = fp.readlines()

7、

>>> lambda x,y: x+y
<function <lambda> at 0x000001C248EC6678>
>>> (lambda x,y: x+y)(3,4) # 因为匿名函数没有名字,使用的时候要用括号把它括起来
7
>>> f = lambda x,y: x+y # 也可以给匿名函数取个名字,像普通函数那样进行调用
>>> f(3, 4)
7

一般情况下,以函数为参数的函数,如过滤函数filter( )、映射函数map( )、排序函数sorted( )等,多使用匿名函数做参数。

>> a = [{'name':'B','age':50},{'name':'A','age':30},{'name':'C','age':40}]
>>> sorted(a, key=lambda x:x['name']) # 按姓名排序
[{'name':'A', 'age':30}, {'name':'B', 'age':50}, {'name':'C', 'age':40}]
>>> sorted(a, key=lambda x:x['age']) # 按年龄排序
[{'name':'A', 'age':30}, {'name':'C', 'age':40}, {'name':'B', 'age':50}]
假如要写一个函数,返回从0到正整数n的所有整数的平方,一般情况下代码写法如下。
>>> def get_square(n):
        result = list()
        for i in range(n):
            result.append(pow(i,2))
        return result

>>> print(get_square(5))
[0, 1, 4, 9, 16]

使用生成器:
>>> def get_square(n):
        for i in range(n):
            yield(pow(i,2))

>>> grator = get_square(5)
>>> for i in grator:
        print(i, end=', ')

0, 1, 4, 9, 16,

9、

>>> import time
>>> def timer(func): # 定义装饰器timer,func是被装饰的函数对象
        def wrapper(*args, **kwds):
            t0 = time.time()
            func(*args, **kwds)
            t1 = time.time()
            print('耗时%0.3f秒'%(t1-t0,))
        return wrapper

>>> @timer
def do_something(delay):
        print('函数do_something开始')
        time.sleep(delay)
        print('函数do_something结束')

>>> do_something(3)
函数do_something开始
函数do_something结束
耗时3.034秒

10、

闭包指的是携带一个或多个自由量的函数。闭包函数的自由量不是函数的参数,而是生成这个函数时的环境变量。闭包一旦生成,自由量会绑定在函数上,即使离开创造它的环境,自由量依旧有效。总结一下,闭包的概念有以下三个要点。
• 闭包是一个函数。
• 闭包函数是由其他代码生成的。
• 闭包函数携带了生成环境的信息。

>>> import math
>>> math.log(math.e) # 返回以e为底e的对数
1.0
>>> math.log2(4) # 返回以2为底4的对数
2.0
>>> math.log10(1000) # 返回以10为底1000的对数
3.0
>>> def glog(b, a): # 返回以a为底b的对数
        return math.log(b)/math.log(a)

>>> glog(25, 5) # 返回以5为底25的对数
2.0

上面为自定义函数

使用闭包,就能制造出和math模块风格一致的对数函数

>> def log_factory(n): # 定义一个对数函数生成器
        def log_n(x): # 生成闭包
            return math.log(x)/math.log(n) # 闭包中携带了环境参数n
        return log_n # 返回闭包

>>> log5 = log_factory(5) # 用闭包生成器生成闭包函数
>>> log7 = log_factory(7) # 用闭包生成器生成闭包函数
>>> log5(25) # 该闭包携带的自由量是5
2.0
>>> log7(49) # 该闭包携带的自由量是7
2.0

如果想要计算以a为底b的对数,则需要使用如下对数换底公式:

三、面向对象

面向对象编程,英文全称为Object Oriented Programming,简称OOP。
类、对象、继承、封装、静态函数、实例方法等概念。

1、

类是对要处理的客观事物的抽象,用来描述具有相同属性和方法的对象的集合,它定义了该集合中每个对象共有的属性和方法。一个类可以实例化为多个对象,对象是类在内存的实例。类是抽象的,不占用存储空间;而对象是具体的,占用存储空间。

2、

类的四个成员

>> class A:
        pass

>>> a = A()
>>> del a
>>> a
Traceback (most recent call last):
  File "<pyshell#70>", line 1, in <module>
    a
NameError: name 'a' is not defined
>>> class B:
        def __del__(self):
            print('执行析构函数,清理现场')
>>> b = B()
>>> del b
执行析构函数,清理现场
>>> b
Traceback (most recent call last):
  File "<pyshell#75>", line 1, in <module>
    b
NameError: name 'b' is not defined


>>> class A:
        def __init__(self): # 定义构造函数
            self.a = 10 # 定义一个成员变量a
        def getA(self): # 定义成员函数
            print("a=%d" % self.a)

>>> a = A() # 实例化
>>> a.getA()
a=10


2、

静态变量一般定义在类的开始位置,独立于构造函数。静态变量既可以用<对象名。变量名>的方式访问,也可以用<类名。变量名>的方式访问。通常,类的静态变量用于保存类的静态属性,该属性可被类的方法使用,但不应该被类的方法修改。
在构造函数中定义的变量称为实例变量。实例变量只能在实例化后使用<对象名。变量名>的方式访问,不能使用<类名。变量名>的方式访问。

> class A:
        static_x = 10 # 静态变量
        def __init__(self):
            self.instance_y = 5 # 实例变量

>>> a = A()
>>> a.static_x # 使用实例名a访问静态变量
10
>>> a.instance_y # 使用实例名a访问实例变量
5
>>> A.static_x # 使用类名A访问静态变量
10
>>> A.instance_y # 使用类名A访问实例变量
Traceback (most recent call last):
  File "<pyshell#89>", line 1, in <module>
    A.instance_y
AttributeError: type object 'A' has no attribute 'instance_y'

3、

  1. 继承
    如果派生类只有一个父类,就是单继承;如果派生类有多个父类,就是多继承。如果父类的构造函数需要参数,则应该显式地调用父类的构造函数,或使用super( )函数,其代码如下。
>>> class Animal:
        def eat(self):
            print('我能吃东西')

>>> class Fash(Animal): # 单继承
        def __init__(self, name):
            self.name = name
        def swim(self):
            print('我会游泳')

>>> class Bird(Animal): # 单继承
        def __init__(self, name):
            self.name = name
        def who(self):
            print('我是%s'%self.name)
        def fly(self):
            print('我会飞')

>>> class Batman(Bird): # 单继承,显式地调用父类的构造函数
        def __init__(self, name, color):
            Bird.__init__(self, name)
            self.color = color
        def say(self):
            print('我会说话,喜欢%s'%self.color)

>>> class Ultraman(Fash, Batman): # 多继承
        def __init__(self, name, color, region):
            super(Ultraman, self).__init__(name)
            super(Fash, self).__init__(name, color)
            self.region=region
        def where(self):
            print('我来自%s'%self.region)

>>> uman = Ultraman('奥特曼', '红色', '火星')
>>> uman.who()
我是奥特曼
>>> uman.where()
我来自火星
>>> uman.say()
我会说话,喜欢红色
>>> uman.eat()
我能吃东西
>>> uman.fly()
我会飞
>>> uman.swim()
我会游泳
2. 封装
封装就是将类的成员变量、成员函数整合在一起,并对关键的信息进行保护或隐藏。Python的信息保护或隐藏分为公有、保护和私有三个级别,下面分别对这三个级别进行讲解。
•  以英文字母开头的成员为公有成员,对类外部的代码均可见。
•  以一个下划线开头的成员为保护成员,对类外部的代码均不可见,但对派生类可见。
•  以两个下划线开头的成员为私有成员,对类外部及派生类都不可见。
>>> class A:
        def __init__(self, a, b, c):
            self.a = a # 公有属性
            self._b = b # 保护属性
            self.__c = c # 私有属性
        def x(self):
            print('公有方法')
        def _y(self):
            print('保护方法')
        def __z(self):
            print('私有方法')
            
>>> a = A(1, 2, 3)
>>> a.a
1
>>> a._b
2
>>> a.__c
Traceback (most recent call last):
  File "<pyshell#209>", line 1, in <module>
    a.__c
AttributeError: 'A' object has no attribute '__c'
>>> a.x()
公有方法
>>> a._y()
保护方法
>>> a.__z()
Traceback (most recent call last):
  File "<pyshell#212>", line 1, in <module>
    a.__z()
AttributeError: 'A' object has no attribute '__z'
以上代码在类A中分别定义了三个级别的属性和方法。测试发现,私有成员的访问受到了限制,但是保护成员在类外部依然可以访问。原来,在Python的OOP中,保护成员和公有成员没有任何区别,保护规则仅在使用星号(*)导入模块的特殊情况下有效。
            
3. 多态
当父类有多个派生类,且派生类都实现了同一个成员函数时,可以实现多态,其代码如下。
>>> class H2O:
        def who(self):
            print("I'm H2O")

>>> class Water(H2O):
        def who(self):
            print("I'm water")

>>> class Ice(H2O):
        def who(self):
            print("I'm ice")

>>> class Vapor(H2O):
        def who(self):
            print("I'm vapor")

>>> def who(obj):
        obj.who()

>>> objs = [H2O(), Water(), Ice(), Vapor()]
>>> for obj in objs:
        who(obj)
  
I'm H2O
I'm water
I'm ice
I'm vapor

6命命规范

名字要尽可能精准表达所代表的对象的含义。
• 名字不要和已有的模块、类、函数或变量名重复。
• 模块名字使用小写字母命名,或首字母小写,不要用下划线。
• 类名使用驼峰(CamelCase)命名风格,首字母大写。
• 类的成员名小写,私有成员以两个下划线开头,保护成员以一个下划线开头。
• 函数名小写,如有多个单词,以下划线分隔。
• 变量名小写,如有多个单词,以下划线分隔。
• 常量名大写,如有多个单词,以下划线分隔。

7缩进、

强烈建议使用4个空格进行缩进,不要使用Tab键进行缩进,更不要将Tab键和空格混用。

8注释

• 行末注释至少使用一个空格和代码语句分开。
• #号和注释内容之间保留一个空格。
• 使用#号注释多行时,中间的空行同样需要使用#号。
• 重要的注释段,使用多个等号隔开可以更加醒目。
• 谨慎使用三引号(无论是单引号还是双引号)注释多行代码。

9引号

编码规范对引号使用几乎没有限制,但是建议遵循如下原则。
• 机器标识符(作为名字的有效字符串集合)使用单引号。
• 自然语言使用双引号。
• 正则表达式使用双引号。
• 文档字符串(DocString)使用三重双引号。

10、

对于空行和空格的使用,建议遵循如下原则。
• 编码格式声明、模块导入、常量和全局变量声明、顶级定义和执行代码之间空两行。
• 顶级定义之间空两行,方法定义之间空一行。
• 在函数或方法内部必要的地方可以空一行以增强节奏感,但应避免连续空行。
• 在二元运算符两边各空一格,算术操作符两边的空格可灵活使用,但两侧务必要保持一致。
• 不要在逗号、分号、冒号前面加空格,但应该在它们后面加(除非在行尾)。
• 函数的参数列表中,逗号之后要有空格。
• 函数的参数列表中,默认值等号两边不要添加空格。
• 左括号之后和右括号之前不要添加空格。
• 参数列表、索引或切片的左括号前不应加空格。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值