美文网首页
Python Study Note(1)

Python Study Note(1)

作者: carolwhite | 来源:发表于2017-08-20 12:45 被阅读16次

变量

  • 除法
>>> 9 / 3
3.0
>>> 10 // 3
3
  • 字符串多个空行
print('''line1
line2
line3''')

list,tuple

  • list:可变数组classmates = ['Michael', 'Bob', 'Tracy']
classmates[-1] #末尾元素
classmates.pop() #删除末尾元素
classmates.pop(1) #删除索引1元素
classmates[1] = "Chen"  ##替代元素
classmates.insert(1,'Jack')
classmates.append('Bai')
  • tuple:不可变数组classmates = ('Michael', 'Bob', 'Tracy')
    t = (1,) #只有一个元素时须加,

条件判断

age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')

":"代表后面缩进的部分都是他的块。

循环

  • for x in ...: 遍历
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    sum = sum + x
print(sum)
  • random()函数:
>>> range(5)
[0, 1, 2, 3, 4]
  • while
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)
  • break:在循环过程中直接退出循环
  • continue:提前结束本轮循环,并直接开始下一循环

字典

判断key是否存在
  • in
>>> 'Thomas' in d
False
  • get
>>> d.get('Thomas') #返回None的时候,交互式命令行不显示结果
>>> d.get('Thomas', -1) #如果key不存在,返回None或者指定的value
-1
基本操作
  • 删除key >>> d.pop('Bob')
set:也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

函数

if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')

函数参数

  • 位置参数 def power(x):
  • 默认参数 def power(x, n=2): # power(5)相当于power(5,2)

注意: 默认参数必须指向不变对象

  • 可变参数:可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
def calc(*numbers): #在函数内部,参数numbers接收到的是一个tuple
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
calc(1, 2)

如果已经有一个list或者tuple

>>> nums = [1, 2, 3]
>>> calc(*nums)
  • 关键字参数:关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

如果已经有一个dict

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
  • 命名关键字参数:如果要限制关键字参数的名字,就可以用命名关键字参数。
def person(name, age, *, city, job): #只接受city,job作为关键字参数
    print(name, age, city, job)

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:

def person(name, age, *args, city, job):
    print(name, age, args, city, job)
  • 参数组合:参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

使用args和*kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。

切片

L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']

>>> L[:3]
['Michael', 'Sarah', 'Tracy']
>>> L[1:3]
['Sarah', 'Tracy']

>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']

tuple和字符串也可以使用。

>>> L[:10:2]  前10个数,每两个取一个:
[0, 2, 4, 6, 8]

高级特性

迭代

dict迭代:默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。

其他语言中是通过下标完成,如下

for (i=0; i<list.length; i++) {
    n = list[i];
}

如果我们希望在python中使用,Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C

以上形式,在python中较为常用。

>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
...     print(x, y)
...
1 1
2 4
3 9
列表生成式
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
生成器

将列表生成器变为生成器

>>> L = [x * x for x in range(10)]
>>> g = (x * x for x in range(10))

>>> next(g)  #一个一个打印
>>> g = (x * x for x in range(10))   #循环打印
>>> for n in g:
...     print(n)
... 

将函数变为生成器:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b               #加入yield
        a, b = b, a + b
        n = n + 1
    return 'done'

>>> for n in fib(6):
...     print(n)
...
1
1
2
3
5
8

例子

def triangles():
    n, L = 1, []
    while True:
        n, L = n+1, [1 if(i == len(L) or i == 0) else  L[i - 1] + L[i] for i in range(len(L)+1)]
        yield L
n = 0

for t in triangles():
    print(t)
    n = n + 1
    if n == 10:
        break

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
迭代器
  • 可迭代对象Iterable:可以直接作用于for循环的对象统称为可迭代对象。一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和带yield的generator function。

可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
  • 迭代器Iterator:可以被next()函数调用并不断返回下一个值的对象称为迭代器,表示的是一个数据流。

可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
  • 把list、dict、str等Iterable变成Iterator可以使用iter()函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

函数式编程

  • map:map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)            #list()函数让它把整个序列都计算出来并返回一个list。
[1, 4, 9, 16, 25, 36, 49, 64, 81]
  • reduce:reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

将str变为int并计算

>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y

...
>>> def char2num(s):
...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579

  • filter:主要用于过滤,把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
def is_odd(n):
    return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
  • sort:除普通排序外,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序。
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] 
def by_name(t): 
    return t[0] 
L2=sorted(L,key=by_name) 

key=str.lower 忽略大小写 reverse=True 反向排序

匿名函数
lambda x: x * x 

**等价于下列内容**
def f(x):
    return x * x
装饰器
def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log  #把@log放到now()函数的定义处,相当于执行了语句:now = log(now)

def now(): 
    print('2015-3')

now()

$ python a.py
call now():
2015-3

带参数的decorator

import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('execute')   #相当于>>> now = log('execute')(now)
偏函数
ef int2(x, base=2):
    return int(x, base)

##把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

>>> import functools
>>> int2 = functools.partial(int, base=2)
内置函数

https://docs.python.org/3/library/functions.html

模块

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '    #文档注释

__author__ = 'Michael Liao'    

import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__=='__main__':    #当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
    test()


使用域
  • 公开的,可以被直接引用:比如:abc,x123,PI等;
  • 特殊的:类似xxx这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的authorname就是特殊变量。
  • 非公开的:类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等。

面向对象编程

访问限制
class Student(object):
    """docstring for Student."""
    def __init__(self, name, score):
        self.__name = name      #__name私有变量
        self.__score = score

    def set_score(self, score):   #从外部修改私有变量,
        self._score = score
    def set_name(self, name):
        self._name =name

    def get_score(self):    #从外部访问获取私有变量
        return self.__score
    def get_name(self):
        return self.__name

    def print_score(self):
        print('%s:%s' % (self._name,self._score))

Bai = Student('Bai', 100)

BaiName = Bai.get_name() 
获取对象信息
  • type
>>> import types
>>> def fn():
...     pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
>>> type('abc')==str
True
>>> type(123)==int
True
  • isinstance:相比较type,更能反映继承关系,同时可以判断是否是某些类型中的一种
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
  • dir:获得一个对象的所有属性和方法。
>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

类似xxx的属性和方法在Python中都是有特殊用途的,下列就是等价的

>>> len('ABC')
3
>>> 'ABC'.__len__()
3

配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态。

>>> class MyObject(object):
...     def __init__(self):
...         self.x = 9
...     def power(self):
...         return self.x * self.x
...

>>> obj = MyObject()

>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
##也可以获取方法
>>> getattr(obj, 'power') # 获取属性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
  • slots:想要限制实例的属性.对继承的无效。
class Student(object):
    __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'

-@property:绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改。Python内置的@property装饰器就是负责把一个方法变成属性调用。

class Student(object):

    def get_score(self):
         return self._score

    def set_score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

上述写法过于复杂,所以需要简化

class Student(object):
#可读可写
    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value
#只可写
    @property
    def age(self):
        return 2015 - self._birth

  • strrepr:用于优化打印结果
class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return 'Student object (name=%s)' % self.name
    __repr__ = __str__

# __str__部分
>>> print(Student('Michael'))    
Student object (name: Michael)

# __repr__部分
>>> s = Student('Michael')
>>> s
<__main__.Student object at 0x109afb310>
  • getattr:如果一个类没有相应属性,那么还可以写一个getattr()方法,动态返回一个属性。一般默认返回None.(只有在没有找到属性的情况下,才调用getattr)
class Student(object):

    def __init__(self):
        self.name = 'Michael'

    def __getattr__(self, attr):
        if attr=='score':
            return 99

  • 枚举
from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)     #value默认从1开始

如果需要更精确地控制枚举类型,可以从Enum派生出自定义类:

from enum import Enum, unique

@unique                              # @unique装饰器可以帮助我们检查保证没有重复值。
class Weekday(Enum):
    Sun = 0 # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

元类
  • type:函数既可以返回一个对象的类型,又可以创建出新的类型。我们说class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。
>>> def fn(self, name='world'): # 先定义函数
...     print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
<class 'type'>
>>> print(type(h))
<class '__main__.Hello'>

要创建一个class对象,type()函数依次传入3个参数:

  1. class的名称;
  2. 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;

本笔记参考 Linux探索之旅

  1. class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。

相关文章

网友评论

      本文标题:Python Study Note(1)

      本文链接:https://www.haomeiwen.com/subject/behirxtx.html