python速记

148 阅读12分钟

1.元组和列表

元组创建

a = 1,2,3
b = (1,2,3) #()可加可不加
c = (1,) # 仅包含一个元素也必须加上,
  • 元组不可修改,列表可修改
元组: nums = (1,2,3,4)
列表: nums = [1,2,3,4]

常用列表方法

  • append
  • clear
  • copy
a = [1,2,3]
b = a # 浅拷贝,b只是a的别名
b = a.copy() # 深拷贝
  • count
# 计算元素出现了多少次
a = [1,3,4,2,1,2,1]
a.count(1) # 等于3

  • extend 列表拼接,无须像"+"一样生成新的一个列表
a = [1,2,4]
b =[4,5,6]
a.extend(b)
  • index 查找元素第一次出现的索引
a = [1,2,4]
a.index(1) #等于0
  • insert 在指定位置插入数据
a = [1,2,3,4,5,6]
a.insert(3, "four")
# 等价于 a[3:3] = "four"
  • pop 删除末尾元素并返回,与append函数配合可将列表作为栈使用
  • remove 移除指定元素
  • sort 对列表就地排序且不返回任何值!
# 如果想获得一个排序后的结果又不想更改原元组的顺序
a = [1,2,3,4]
# b = a.sort()  # b为空
b = a.copy()
b.sort()

字符串

设置字符串的格式

1.类C版

format = "hello, %s. %s enough for you?"
values = ("world", "hot")
printstr= format % values

2.推荐使用字符串format方法

str = "{}, {} and {}".format("first", "second", "third")
# 也可以如下:,输出 to be or not to be
str = "{3} {0} {2} {1} {3} {0}".format("be", "not", "or", "to")
# 也可以
str = "{id} is {name}".format(id = 12, name = "zhu")


########
# 变量与替换字段同名,可以使用如下写法:
from math import e
f"Euler`s constant is roughtly {e}."

# 设置精度和宽度
"{num:.2f} and {name:10}".format(num = 1.23123, name = "zhujinde")
####

字符串方法

  • find 查找子串,找到返回首字母索引,找不到则-1
  • join 合并序列的元素,只能对字符串进行合并
num = ['1', '2', '3', '4']
seq = "+"
str = seq.join(num) # str = "1+2+3+4"
  • lower 返回字符串的小写版本
  • replace 子串替换
"this is a test".replace("is", "eez")
  • split 根据给定字符进行字符串拆分
str = "1+2+3+4"
s = str.split('+') # s = ['1', '2', '3', '4']

字典

字典方法

  • clear 原地删除所有字典项,返回none,原字典成为{}
d ={}
d["name"] = "zhu"
return_value = d.clear()
# 此时 d = {}, return_value = None
  • copy 复制字典,但为浅复制,因为值本身是原件。深拷贝使用deepcopy。
x = {"id":12}
# 浅拷贝
y = x.copy()
# 深拷贝
z = deepcopy(x)
  • fromkeys 创建一个新的字典,其中包含指定的键盘,且每个键对应的都是none
mydict = {}.fromkeys(["name", "age"])
# 上面多了个临时字典{},推荐直接使用以下方式:
mydict = dict.fromkeys(["name", "age"])
  • get 相比mydict["name"]的直接访问方法,get在key不存在时不会抛出异常,而是会返回None,也可以指定默认错误返回值
mydict = {}.fromkeys(["name", "age"])
mydict["grade"]  # 执行错误,异常
mydict.get("grade") # 返回none
mydict.get("grade", "N/A") # 返回 N/A
  • items 返回一个包含所有字典项的列表,每个元素都为(key, value)形式,排序不定。返回值为一种名为 字典视图 的特殊类型
mydict = {}.fromkeys(["name", "age"])
print(mydict.items()) # 输出dict_items([('name', None), ('age', None)])
  • keys 返回所有键值的字典视图

mydict = {}.fromkeys(["name", "age"])
print(mydict.keys())
#
  • pop 获取指定key对应的值,并将其从字典中删除
  • update 使用一个字典中的项来更新另一个字典。没有的k-v直接添加,相同的Key就更新
ori = {
    "title" : "tx",
    "url" : "www.qq.com"
}
newInfo = {"title" : "alibaba", "url" : "www.alibaba.com", "place" : "hangzhou"}
ori.update(newInfo)
print(ori) # 输出{'title': 'alibaba', 'url': 'www.alibaba.com', 'place': 'hangzhou'}
  • values 返回值的字典视图

一些特殊函数

  • exec 函数exec将字符串作为代码执行,无返回值。为避免所执行的字符串中的变量和外部的变量产生冲突,我们可以加入一个命名空间。
from math import sqrt

scope = {} # 命名空间
exec("sqrt = 1", scope) # sqrt属于命名空间scope,不会和外部的sqrt函数冲突
sqrt(4) # 输出2.0
## 可以以如下方式在命名空间中添加新的值
scope['x'] = 2
scope['y'] = 3
  • eval 功能类似exec,但使用字符串返回执行的字符串的返回值
scope = {}
scope['x'] = 2
scope['y'] = 3
print(eval("x * y", scope)) # 输出6
  • 不定长参数 *params:不会收集关键字参数,收集到的输入参数是一个元祖;
    **params :会收集关键字参数,收集到的输入是一个字典;
def fun1(x, *y, z):
    print(x, y, z)
    
# 如果*params不在最后一位,需要显示指定后续参数
fun1(1, 2, 3, 4, z =5)

#
def fun2(x, y, z = 3, *pospar, **keypar):
    print(x, y, z)
    print(pospar)
    print(keypar)
    
fun2(1,2,3,4,5,6,7, foo = 1, bar = 2)

` 输出如下:
1 2 3
(4, 5, 6, 7)
{'foo': 1, 'bar': 2}
`
  • map(func, seq) 对序列seq中的所有函数执行func
a = list(map(str, range(10))) # 与str(i) for i int range(10)等价
print(a) # list:将元组转换为数组。输出['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  • filter(func, seq) 过滤操作,返回一个列表,期中包含对func执行结果为真的所有结果
def func(x):
    return x.isalnum()
    
seq = ["foo", "x31", "?12", "*^&*"]
a = list(filter(func, seq))
print(a) # 输出['foo', 'x31']

类似静态变量和成员变量

class test:
    member = 0
    def init(self):
        test.member += 1 # 类似静态变量,member由所有类成员实例维护
        # self.member += 1 # 修改的member只属于当前变量

    def xprint(self):
        print(self.member)

私有成员和方法

要让方法或属性成为私有的(不能从外部访问),只需让其名称以两个下划线打头即可。

class Secretive:
    def __inaccessible(self):
    print("Bet you can't see me ...")

def accessible(self):
    print("The secret message is:") 
    self.__inaccessible()

现在从外部不能访问__inaccessible,但在类中(如accessible中)依然可以使用它。 虽然以两个下划线打头有点怪异,但这样的方法类似于其他语言中的标准私有方法。然而,幕后的处理手法并不标准:在类定义中,对所有以两个下划线打头的名称都进行转换,即在开头加上一个下划线和类名。

>>> Secretive._Secretive__inaccessible 
<unbound method Secretive.__inaccessible>

只要知道这种幕后处理手法,就能从类外访问私有方法,然而不应这样做。

>>> s._Secretive__inaccessible() 
Bet you can't see me ...

总之,你无法禁止别人访问对象的私有方法和属性,但这种名称修改方式发出了强烈的信号, 让他们不要这样做。

如果你不希望名称被修改,又想发出不要从外部修改属性或方法的信号,可用一个下划线打头。这虽然只是一种约定,但也有些作用。例如,from module import *不会导入以一个下划线打头的名称。

调用超类的构造函数

class Bird:
    def __init__(self):
        self.hungry = True def 
    
    eat(self):
        if self.hungry: 
            print('Aaaah ...') 
            self.hungry = False
        else:
            print('No, thanks!')

class SongBird(Bird): 
    def __init__(self):
        # Bird.__init__(self) 
        ##或者使用函数super()
        super().__init__()
        self.sound = 'Squawk!' 
        
    def sing(self):
        print(self.sound)

函数property

函数property使用起来很简单。如果你编写了一个类,如前一节的Rectangle类,只需再添加 一行代码。


class Rectangle:
     def __init__ (self):
     self.width = 0 
     self.height = 0
    
    def set_size(self, size):
         self.width, self.height = size 
         
    def get_size(self):
        return self.width, self.height 
    
    size = property(get_size, set_size)

在这个新版的Rectangle中,通过调用函数property并将存取方法作为参数(获取方法在前, 设置方法在后)创建了一个特性,然后将名称size关联到这个特性。这样,你就能以同样的方式 对待width、height和size,而无需关心它们是如何实现的。

r = Rectangle() 
r.width = 10 
r.height = 5 
>>> r.size
(10, 5)
>>> r.size = 150, 100
>>> r.width 
150

如你所见,属性size依然受制于get_size和set_size执行的计算,但看起来就像普通属性一样。

实际上,调用函数property时,还可不指定参数、指定一个参数、指定三个参数或指定四 个参数。如果没有指定任何参数,创建的特性将既不可读也不可写。如果只指定一个参数(获取方法),创建的特性将是只读的。第三个参数是可选的,指定用于删除属性的方法(这个方 法不接受任何参数)。第四个参数也是可选的,指定一个文档字符串。这些参数分别名为fget、fset、fdel和doc。如果你要创建一个只可写且带文档字符串的特性,可使用它们作为关键字参数来实现。

本节虽然很短(旨在说明函数property很简单),却非常重要。这里要说明的是,对于新式类,应使用特性而不是存取方法。

深度探索继承

要确定一个类是否是另一个类的子类,可使用内置方法issubclass。

>>> issubclass(SPAMFilter, Filter)
True 11 >>> issubclass(Filter, SPAMFilter)
False

如果你有一个类,并想知道它的基类,可访问其特殊属性__bases__。

SPAMFilter.__bases__
(<class __main__.Filter at 0x171e40>,) 
Filter.__bases__
(<class 'object'>,)

同样,要确定对象是否是特定类的实例,可使用isinstance。

s = SPAMFilter()
isinstance(s, SPAMFilter)
True
isinstance(s, Filter)
True
isinstance(s, str) 
False
使用isinstance通常不是良好的做法,依赖多态在任何情况下都是更好的选择。一个
重要 的例外情况是使用抽象基类和模块abc时。

如你所见,s是SPAMFilter类的(直接)实例,但它也是Filter类的间接实例,因为SPAMFilter 是Filter的子类。换而言之,所有SPAMFilter对象都是Filter对象。从前一个示例可知,isinstance 也可用于类型,如字符串类型(str)。

如果你要获悉对象属于哪个类,可使用属性__class__。

s.__class__
<class __main__.SPAMFilter at 0x1707c0>

相关函数

callable(object)  判断对象是否是可调用的(如是否是函数或方法)
getattr(object,name[,default])  获取属性的值,还可提供默认值
hasattr(object, name)  确定对象是否有指定的属性
isinstance(object, class)  确定对象是否是指定类的实例
issubclass(A, B)  确定A是否是B的子类
random.choice(sequence)  从一个非空序列中随机地选择一个元素
setattr(object, name, value) 将对象的指定属性设置为指定的值
type(object) 返回对象的类型

静态方法和类方法

讨论旧的特性实现方式之前,先来说说另外两种实现方式类似于新式特性的功能。静态方法 和类方法是这样创建的:将它们分别包装在staticmethod和classmethod类的对象中。静态方法的 定义中没有参数self,可直接通过类来调用。类方法的定义中包含类似于self的参数,通常被命 名为cls。对于类方法,也可通过对象直接调用,但参数cls将自动关联到类。下面是一个简单的 示例:

class MyClass:
    def smeth():
        print("this is a static method")
    smeth = staticmethod(smeth)

    def cmeth(cls):
        print('This is a class method of', cls)
    cmeth = classmethod(cmeth)

像这样手工包装和替换方法有点繁琐。在Python 2.4中,引入了一种名为装饰器的新语法, 可用于像这样包装方法。(实际上,装饰器可用于包装任何可调用的对象,并且可用于方法和函 数。)可指定一个或多个装饰器,为此可在方法(或函数)前面使用运算符@列出这些装饰器(指定了多个装饰器时,应用的顺序与列出的顺序相反)。

class MyClass:
     @staticmethod 
     def smeth():
         print('This is a static method')
         
     @classmethod
     def cmeth(cls):
         print('This is a class method of', cls)

定义这些方法后,就可像下面这样使用它们(无需实例化类):

>>> MyClass.smeth()
This is a static method
>>> MyClass.cmeth()
This is a class method of <class '__main__.MyClass'>

异常

内置的异常类

Exception        几乎所有的异常类都是从它派生而来的
AttributeError   引用属性或给它赋值失败时引发
OSError          操作系统不能执行指定的任务(如打开文件)时引发,有多个子类
IndexError       使用序列中不存在的索引时引发,为LookupError的子类
KeyError         使用映射中不存在的键时引发,为LookupError的子类\
NameError        找不到名称(变量)时引发
SyntaxError      代码不正确时引发
TypeError        将内置操作或函数用于类型不正确的对象时引发
ValueError       其类型正确但包含的值不合适
ZeroDivisionError  在除法或求模运算的第二个参数为零时引发

向上传播异常

捕获异常后,如果要重新引发它(即继续向上传播),可调用raise且不提供任何参数

class MuffledCalculator:
    muffled = False
    def calc(self, expr): 
        try:
            return eval(expr) 
        except ZeroDivisionError: 
            if self.muffled:
                print('Division by zero is illegal') 
            else:
                raise

万事大吉时

在有些情况下,在没有出现异常时执行一个代码块很有用。为此,可像条件语句和循环一样, 给try/except语句添加一个else子句。

try:
    print('A simple task')
except:
    print('What? Something went wrong?')
else:
    print('Ah ... It went as planned.')

如果你运行这些代码,输出将如下:

A simple task\
Ah ... It went as planned.

通过使用else子句,可实现8.3.3节所说的循环。

while True: 
    try:
        x = int(input('Enter the first number: '))
        y = int(input('Enter the second number: ')) 
        value = x / y
        print('x / y is', value)
    except:
        print('Invalid input. Please try again.')
    else: 
        break

在这里,仅当没有引发异常时,才会跳出循环(这是由else子句中的break语句实现的)。换 而言之,只要出现错误,程序就会要求用户提供新的输入。

生成器

生成器是一个相对较新的Python概念。由于历史原因,它也被称为简单生成器(simple generator)。生成器是一种使用普通函数语法定义的迭代器。

生成器创建起来与函数一样简单。你现在肯定厌烦了老套的斐波那契数列,所以下面换换口 味,创建一个将嵌套列表展开的函数。这个函数将一个类似于下面的列表作为参数:

nested = [[1, 2], [3, 4], [5]]

换而言之,这是一个列表的列表。函数应按顺序提供这些数字,下面是一种解决方案:

def flatten(nested):
    for sublist in nested:
        for element in sublist: 
            yield element

这个函数的大部分代码都很简单。它首先迭代所提供嵌套列表中的所有子列表,然后按顺序 迭代每个子列表的元素。倘若最后一行为print(element),这个函数将容易理解得多,不是吗?

在这里,你没有见过的是yield语句。包含yield语句的函数都被称为生成器。这可不仅仅是 名称上的差别,生成器的行为与普通函数截然不同。差别在于,生成器不是使用return返回一个 值,而是可以生成多个值,每次一个。每次使用yield生成一个值后,函数都将冻结,即在此停止执行,等待被重新唤醒。被重新唤醒后,函数将从停止的地方开始继续执行。

为使用所有的值,可对生成器进行迭代。

>>> nested = [[1, 2], [3, 4], [5]]
>>> for num in flatten(nested):
... print(num) ...
1 2 3 4 5

>>> list(flatten(nested)) 
[1, 2, 3, 4, 5]

从任意长度的可迭代对象中分解元素

def drop_first_last():
    record = ('dave', '192312031', '777-23134', 'dava@example.com')
    first, *middle, last = record
    return middle

魔方方法

www.cnblogs.com/ningxinjie/… blog.csdn.net/qq_40196164…

with 上下文管理器

www.cnblogs.com/pythonbao/p…