python篇-基础知识2

字符串方法

  • find

    • 可以指定搜索的起点和重点
    • 指定的范围包括起点,但不包括终点
  • join

    • >>> seq = [1, 2, 3, 4, 5] 
      >>> sep = '+' 
      >>> sep.join(seq) # 尝试合并一个数字列表Traceback (most recent call last):   File "<stdin>", line 1, in ? TypeError: sequence item 0: expected string, int found 
      >>> seq = ['1', '2', '3', '4', '5'] 
      >>> sep.join(seq) # 合并一个字符串列'1+2+3+4+5' 
      >>> dirs = '', 'usr', 'bin', 'env' 
      >>> '/'.join(dirs) '/usr/bin/env' 
      >>> print('C:' + '\\'.join(dirs)) C:\usr\bin\env 
      
    • 所合并序列都必须是字符串

  • lower

    返回小写版本

  • replace

    >>> 'This is a test'.replace('is', 'eez') 'Theez eez a test' 
    
  • split

    >>> '1+2+3+4+5'.split('+') 
    ['1', '2', '3', '4', '5'] 
    >>> '/usr/bin/env'.split('/') 
    ['', 'usr', 'bin', 'env'] 
    >>> 'Using the default'.split() 
    ['Using', 'the', 'default']
    

    注意,如果没有指定分隔符,将默认在单个或多个连续的空白字符(空格、制表符、换行符等)处进行拆分

  • strip

    去除开头和结尾的空白,但不包括中间的

  • translate

    方法translate与replace一样替换字符串的特定部分,但不同的是它只能进行单字符替换。这个方法的优势在于能够同时替换多个字符,因此效率比replace高

  • 判断字符串是否满足某些条件

    isalnum、isalpha、isdecimal、isdigit、isidentifier、islower、isnumeric、isprintable、isspace、istitle、isupper

字典

字典是python中唯一的内置映射类型

  • 创建字典

    phonebook = {'Alice':'2341','Beth':'9102','Ceil':'3258'}
    
  • 函数dict

    >>> items = [('name', 'Gumby'), ('age', 42)] >>> d = dict(items) 
    >>> d {'age': 42, 'name': 'Gumby'} 
    >>> d['name'] 'Gumby'
    

    还可使用关键字实参来调用这个函数,如下所示

    >>> d = dict(name='Gumby', age=42) 
    >>> d {'age': 42, 'name': 'Gumby'}
    
  • 基本的字典操作

    • len(d)

      返回包含的键值对数

    • d[k]

      返回与键k相关联的值

    • d[k] = v

      将值v关联到键k

    • del d[k]

      删除键为k的项

    • k in d

      检查字典d是否包含键为k的项

  • 键的类型

    字典中的键可以是整数,但并非必须是整数。字典中的键可以是任何不可变

    的类型,如浮点数(实数)、字符串或元组

  • 自动添加

    • 即便是字典中原本没有的键,也可以给它赋值,这将在字典中创建一个新项。

    • 然而,如果不使用append或其他类似的方法,就不能给列表中没有的元素赋值

  • 成员资格

    表达式k in d(其中d是一个字典)查找的是键而不是值

    表达式v in l(其中l是一个列表)查找的是值而不是索引

    这看似不太一致,但你习惯后就会觉得相当自然。毕竟如果字典包含指定的

    键,检查相应的值就很容易

字典的内置方法

  • clear

    删除所有的字典项

  • copy

    copy为浅复制,即修改复制后的会影响原来的

    可以使用copy中的函数deepcopy进行深复制

    >>> from copy import deepcopy 
    >>> d = {} 
    >>> d['names'] = ['Alfred', 'Bertrand'] 
    >>> c = d.copy() 
    >>> dc = deepcopy(d)
    
  • fromkeys

    >>> dict.fromkeys(['name', 'age'])
    {'age': None, 'name': None
    

    如果你不想使用默认值None,可提供特定的值

    >>> dict.fromkeys(['name', 'age'], '(unknown)') 
    {'age': '(unknown)', 'name': '(unknown)
    
  • get

    方法get为访问字典项提供了宽松的环境。通常,如果你试图访问字典中没有的项,将引发错误

    >>> d = {} 
    >>> print(d['name']) Traceback (most recent call last):   File "<stdin>", line 1, in ? KeyError: 'name' 
    

    而使用get不会这样

    >>> print(d.get('name')) 
    None
    >>> d.get('name', 'N/A') 
    'N/A'
    
  • items

    方法items返回一个包含所有字典项的列表,其中每个元素都为(key, value)

    的形式。字典项在列表中的排列顺序不确定

  • keys

    返回一个字典视图,其中包含指定字典中的键

  • pop

    方法pop可用于获取与指定键相关联的值,并将该键值对从字典中删除

  • popitem

    方法popitem类似于list.pop,但list.pop弹出列表中的最后一个元素,而

    popitem随机地弹出一个字典项,因为字典项的顺序是不确定的,没有“最后

    一个元素”的概念。

    如果你要以高效地方式逐个删除并处理所有字典项,这可能很有用,因为这样

    无需先获取键列表

  • setdefault

    方法setdefault有点像get,因为它也获取与指定键相关联的值,但除此之

    外,setdefault还在字典不包含指定的键时,在字典中添加指定的键值对

    • dic = {"one":1,"two":2}
      dic.setdefault("three",3)
      
    • 返回值

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6u300esP-1635823411541)(https://i.loli.net/2021/04/08/mi1VNnEbUMuGPAg.png)]

  • update

    方法update使用一个字典中的项来更新另一个字典

  • values

    方法values返回一个由字典中的值组成的字典视图。不同于方法keys,方法

    values返回的视图可能包含重复的值

条件、循环及其他语句

  • 打印多个参数

    你可同时打印多个表达式,条件是用逗号分隔它们:

    >>> print('Age:', 42)
    Age: 42 
    

    如你所见,在参数之间插入了一个空格字符。在你要合并文本和变量

    值,而又不想使用字符串格式设置功能时,这种行为很有帮助

    >>> name = 'Gumby' 
    >>> salutation = 'Mr.' 
    >>> greeting = 'Hello,' 
    >>> print(greeting, salutation, name) 
    Hello, Mr. Gumby 
    

    如果字符串变量greeting不包含逗号,如何在结果中添加呢?你不能

    像下面这样做

    print(greeting, ',', salutation, name)
    

    因为这将在逗号前添加一个空格。下面是一种可行的解决方案

    print(greeting + ',', salutation, name)
    

    它将逗号和变量greeting相加。如果需要,可自定义分隔符

    >>> print("I", "wish", "to", "register", "a", "complaint", sep="_") I_wish_to_register_a_complaint 
    

    你还可自定义结束字符串,以替换默认的换行符。例如,如果将结束

    字符串指定为空字符串,以后就可继续打印到当前行

    print('Hello,', end='') 
    print('world!')
    

    上述代码打印Hello, world!

赋值魔法

  • 序列解包

    这在使用返回元组(或其他序列或可迭代对象)的函数或方法时很有用。假设要从字典中随便获取(或删除)一个键值对,可使用方法popitem,它随便获取一个键值对并以元组的方式返回。接下来,可直接将返回的元组解包到两个变量中

    >>> scoundrel = {'name': 'Robin', 'girlfriend': 'Marion'} 
    >>> key, value = scoundrel.popitem() 
    >>> key 'girlfriend' 
    >>> value 'Marion'
    

    可使用星号运算符(*)来收集多余的值,这样无需确保值和变量的个数相同,如下例所示

    >>> a, b, *rest = [1, 2, 3, 4] 
    >>> rest 
    [3, 4] 
    

    还可将带星号的变量放在其他位置

    >>> name = "Albus Percival Wulfric Brian Dumbledore" 
    >>> first, *middle, last = name.split() 
    >>> middle 
    ['Percival', 'Wulfric', 'Brian'] 
    

    赋值语句的右边可以是任何类型的序列,但带星号的变量最终包含的

    总是一个列表。在变量和值的个数相同时亦如此

    >>> a, *b, c = "abc" 
    >>> a, b, c 
    ('a', ['b'], 'c') 
    

代码块

在Python中,使用冒号(:)指出接下来是一个代码块,并将该代码块中

的每行代码都缩进相同的程度

  • 条件和条件语句

    用作布尔表达式(如用作if语句中的条件)时,下面的值都将被解释器视为假:

    False None 0 “” () [] {}

    换而言之,标准值False和None、各种类型(包括浮点数、复数等)的数值0、空序列(如空字符串、空元组和空列表)以及空映射(如空字典)都被视为假,而其他各种值都被视为真,包括特殊值True

    • 实际上,True和False不过是0和1的别名,虽然看起来不同,但作用是相同的。
    >>> True 
    True 
    >>> False 
    False 
    >>> True == 1 
    True 
    >>> False == 0 
    True 
    >>> True + False + 42 
    43 
    
    • else语句
    name = input('What is your name?') 
    if name.endswith('Gumby'):     
        print('Hello, Mr. Gumby') 
    else:    
        print('Hello, stranger') 
    
    • elif子句
  • 比较运算符

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Y1aSLqm-1635823411543)(https://i.loli.net/2021/04/08/YjOxFE2tCoUNHpr.png)]

  • 顺序值和符号

    要获悉字母的顺序值,可使用函数ord。这个函数的作用与函数chr

    相反

    >>> ord("") 
    128585 
    >>> ord("") 
    128586 
    >>> chr(128584) 
    ''
    
  • and、or、not

断言

>>> age = 10 
>>> assert 0 < age < 100 
>>> age = -1 
>>> assert 0 < age < 100 
Traceback (most recent call last):    File "<stdin>", line 1, in ? AssertionError

可在条件后面加上一个字符串,对断言做出说明

>>> age = -1 
>>> assert 0 < age < 100, 'The age must be realistic' Traceback (most recent call last):     File "<stdin>", line 1, in ? AssertionError: The age must be realistic 

循环

  • while循环

  • for循环

  • 迭代字典

    for key, value in d.items():    
        print(key, 'corresponds to', value)
    
  • 并行迭代

    image-20210408093742530

简单推导

>>> [x * x for x in range(10)] 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]
>>> [(x, y) for x in range(3) for y in range(3)] 
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

好像if只能有一个

三人行

  • pass

    python中代码块不能为空,此时就能用pass来解决

    if name == 'Ralph Auldus Melish':               
        print('Welcome!') 
    elif name == 'Enid':    
     # 还未完成......   
     pass 
    elif name == 'Bill Gates':    
     print('Access Denied')
    
  • del

    垃圾收集

    >>> scoundrel = {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'} 
    >>> robin = scoundrel 
    >>> scoundrel {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'} 
    >>> robin {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'} 
    >>> scoundrel = None 
    >>> robin {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'} 
    >>> robin = None
    
    • 最初,robin和scoundrel指向同一个字典,因此将None赋给scoundrel后,依然可以通过robin来访问这个字典。但robin也设置为None之后,这个字典就漂浮在计算机内存中,没有任何名称与之相关联,再也无法获取或使用它了。因此,智慧无穷的Python解释器直接将其删除。这被称为垃圾收集。请注意,在前面的代码中,也可将其他任何值(而不是None)赋给两个变量,这样字典也将消失
    • 另一种办法是使用del语句。(第2章和第4章使用这条语句来删除序列和字典,还记得吗?)这不仅会删除到对象的引用,还会删除名称本身
  • 使用exec和eval执行字符串及计算机其结果

    exec eval 最好提供命名空间

函数

  • 定义
def hello(name):
    return 'hello,'+name+'!'
  • 如果参数不可变

    在有些语言(如C++、Pascal和Ada)中,经常需要给参数

    赋值并让这种修改影响函数外部的变量。

    在Python中,没法直接这样做,只能修改参数对象本身。

    如果参数是不可变的(如数)呢?

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HTMzW02L-1635823411545)(https://i.loli.net/2021/04/08/puzCc1y6Um8EVLP.png)]

  • 函数参数的顺序

    >>> hello_1(greeting='Hello', name='world') 
    Hello, world!
    

    像这样使用名称指定的参数称为关键字参数,主要优点是有

    助于澄清各个参数的作用。

  • 关键字参数可以指定参数的默认值

    def hello_3(greeting='Hello', name='world'):     
        print('{}, {}!'.format(greeting, name)
    
    >>> hello_3() Hello, world! 
    >>> hello_3('Greetings') 
    Greetings, world! 
    >>> hello_3('Greetings', 'universe') 
    Greetings, universe
    

参数收集

def print_params(*params):
    print(params)
    
>>> print_params('Testing') 
('Testing',)

参数前面的星号将提供的所有值都放在一个元组中,也就是将这些值收集起来。

这样的行为我们在5.2.1节见过:赋值时带星号的变量收集多余的值。它收集的是列表而不是元组中多余的值,但除此之外,这两种用法很像

与赋值时一样,带星号的参数也可放在其他位置(而不是最后),但不同的是,在这种情况下你需要做些额外的工作:使用名称来指定后续参数

>>> def in_the_middle(x, *y, z):
...     print(x, y, z) 
... 
>>> in_the_middle(1, 2, 3, 4, 5, z=7) 
1 (2, 3, 4, 5) 7 
>>> in_the_middle(1, 2, 3, 4, 5, 7) 
Traceback (most recent call last):    File "<stdin>", line 1, in <module> TypeError: in_the_middle() missing 1 required keyword-only argument: '

要收集关键字参数,可使用两个星号

>>> def print_params_3(**params): 
...     print(params) 
... 
>>> print_params_3(x=1, y=2, z=3) 
{'z': 3, 'x': 1, 'y': 2} 
def print_params_4(x, y, z=3, *pospar, **keypar):  
    print(x, y, z)    
    print(pospar)    
    print(keypar)
>>> print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2) 
1 2 3 
(5, 6, 7) 
{'foo': 1, 'bar': 2} 
>>> print_params_4(1, 2) 
1 2 3 
() 
{}

分配参数

def add(x, y):     
    return x + y

params = (1, 2)
>>> add(*params) 
3

格式化输出

  • name = liwei
    print("{name} hello")
    
  • print("{} hello".format(name));
    

变量遮盖问题

如果需要,可使用函数globals来访问全局变量。这个函数类似于vars,返回一个包含全局变量的字典。(locals返回一个包含局部变量的字典。)

>>> def combine(parameter):
... print(parameter + globals()['parameter']) ... 
>>> parameter = 'berry' 
>>> combine('Shrub') 
Shrubberry

函数嵌套

def multiplier(factor):    
    def multiplyByFactor(number):     
        return number * factor    
    return multiplyByFactor 

在这里,一个函数位于另一个函数中,且外面的函数返回里面的函数。也就是返回一个函数,而不是调用它。重要的是,返回的函数能够访问其定义所在的作用域。换而言之,它携带着自己所在的环境(和相关的局部变量)!

创建类

class Person:
    def set_name(self,name):
        self.name = name
	def get_name(self):
        return self.name
    def greet(self):
        print("Hello,world!I'm{}".format(self.name))

self指向对象本身

  • 让另一个变量指向同一个方法
>>> class Bird: 
...     song = 'Squaawk!' 
...     def sing(self): 
...         print(self.song) 
... 
>>> bird = Bird() 
>>> bird.sing() 
Squaawk! 
>>> birdsong = bird.sing 
>>> birdsong() 
Squaawk!
  • 获取私有变量和私有方法的效果
class Secretive:     
    def __inaccessible(self):  
        print("Bet you can't see me ...")    
	def accessible(self):  
        print("The secret message is:")  
        self.__inaccessible() 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLsxo4YG-1635823411547)(https://i.loli.net/2021/04/09/nCNwGiJZd79IVEs.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AW4r1Onf-1635823411548)(https://i.loli.net/2021/04/09/SQtXgE1DueBbN9j.png)]

命名空间

在class语句中定义的代码都是在一个特殊的命名空间(类的命名空间内)执行的,而类的所有成员都可以访问这个命名空间

class MemberCounter:     
    members = 0    
    def init(self):  
        MemberCounter.members += 1 
>>> m1 = MemberCounter() 
>>> m1.init() 
>>> MemberCounter.members 
1 
>>> m2 = MemberCounter() 
>>> m2.init() 
>>> MemberCounter.members 
2 

如果你在一个实例中给属性members赋值,结果将如何呢

>>> m1.members = 'Two' 
>>> m1.members 
'Two' 
>>> m2.members 
2 

新值被写入m1的一个属性中,这个属性遮住了类级变量。这类似于第6章的旁注“遮盖的问题”所讨论的,函数中局部变量和全局变量之间的关系

超类和子类

  • 指定超类
class Filter:     
    def init(self):     
        self.blocked = []    
	def filter(self, sequence):  
        return [x for x in sequence if x not in self.blocked] 

class SPAMFilter(Filter): # SPAMFilter是Filter的子类   
    def init(self): # 重写超类Filter的方法init  
    	self.blocked = ['SPAM'] 

继承

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

>>> s = SPAMFilter() 
>>> isinstance(s, SPAMFilter) 
True 
>>> isinstance(s, Filter) 
True 
>>> isinstance(s, str) 
False 

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

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

多个超类

class Calculator:     
    def calculate(self, expression):  
        self.value = eval(expression) 
        
class Talker:    
    def talk(self):   
        print('Hi, my value is', self.value) 
        
class TalkingCalculator(Calculator, Talker):    
    pass 

这被称为多重继承,是一个功能强大的工具。然而,除非万不得已,否则应避免使用多重继承,因为在有些情况下,它可能带来意外的“并发症”

  • 如果多个超类含有同名的方法

    必须在class语句中小心排列这些超类,因为位于前面的类的方法将覆盖位于后面的类的方法。因此,在前面的示例中,如果Calculator类包含方法talk,那么这个方法将覆盖Talker类的方法talk(导致它不可访问)

构造函数

class FooBar:     
    def __init__(self):  
        self.somevar = 42 
>>> f = FooBar() 
>>> f.somevar 
42

set集合

  • 不重复性
  • 不支持下标访问
  • 添加方法为add

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bWgL12d5-1635823411550)(https://i.loli.net/2021/04/09/zWjfa52GYqCuHMI.png)]

类方法和函数

​ 实际上,方法和函数的区别表现在前一节提到的参数self上。方法(更准确地说是关联的方法)将其第一个参数关联到它所属的实例,因此无需提供这个参数。无疑可以将属性关联到一个普通函数,但这样就没有特殊的self参数了

>>> class Class: 
...		def method(self): 
...     	print('I have a self!') 
... 
>>> def function(): 
...     print("I don't...") 
... 
>>> instance = Class() 
>>> instance.method() 
I have a self! 
>>> instance.method = function 
>>> instance.method() 
I don't

抽象基类

from abc import ABC, abstractmethod  
class Talker(ABC):    
    @abstractmethod    
    def talk(self):  
        pass

这里的要点是你使用@abstractmethodS来将方法标记为抽象的——在子类中必须实现的方法

  • 集成抽象基类进行实例化
class Knigget(Talker):
    def talk(self):
        print("ni!")

调用未关联的超类构造函数和使用函数Super

  • 未关联的超类构造函数

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

    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):  
            super().__init__
    

    你无需知道函数super的内部工作原理,但必须知道的是,使用函数super比调用超类的未关联构造函数(或其他方法)要好得多。函数super返回的到底是什么呢?通常,你无需关心这个问题,只管假定它返回你所需的超类即可。实际上,它返回的是一个super对象,这个对象将负责为你执行方法解析。当你访问它的属性时,它将在所有的超类(以及超类的超类,等等)中查找,直到找到指定的属性或引发AttributeError异常

函数property

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  

迭代器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzukomorebi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值