Python笔记【五】

本文为博主原创,未经许可严禁转载。
本文链接:https://blog.csdn.net/zyooooxie/article/details/108181446

这是我的博客里 关于python的category , 有兴趣,看一看。

个人博客:https://blog.csdn.net/zyooooxie

字典的get()

https://docs.python.org/zh-cn/3.7/library/stdtypes.html#dict.get

访问dict里的值,最简单的方式:只需要 dict[key],但该键若是不存在,就会抛出KeyError。

还有 get() 提供了一个比较宽松的方式去访问字典项;当键不存在的时候,get()不报错,只是返回一个None;

但我有个疑问,若此key对应value是None,咋整呢? 对,我会把value设为None

如何区分 None是 某key不存在时的返回值 还是 此key本身的value呢

我的思路就是 先判断下key 在不在dict.keys(),若在,是value的None;不在,是默认返回值的None。

在这里插入图片描述

静态方法、类方法、实例方法

https://docs.python.org/zh-cn/3.7/library/functions.html#classmethod

https://docs.python.org/zh-cn/3.7/library/functions.html#staticmethod

# 在一个类中,可能出现三种方法: 实例方法、静态方法和类方法

# 实例方法的第一个参数必须是”self”,实例方法只能通过类实例[self]进行调用。这时候“self”就代表这个类实例本身;通过”self”可以直接访问实例的属性。
# 类方法以cls作为第一个参数,cls表示类本身,定义时使用@classmethod装饰器。通过cls可以访问类的相关属性;
# 静态方法没有参数限制,既不需要实例参数,也不需要类参数,定义的时候使用@staticmethod装饰器。


# 主要区别在于参数,实例方法被绑定到一个实例,只能通过实例对象进行调用;
# 但是对于静态方法和类方法,可以通过类对象和实例对象两种方式进行调用;


def test_0():
    # 类里的方法有3种:实例方法,类方法,静态方法

    # 实例方法被绑定到一个实例,只能通过实例对象进行调用;
    # 但是对于静态方法和类方法,可以通过类对象和实例对象两种方式进行调用;

    # 名称	    定义方法	                                                        权限	                                            调用方法
    # 实例方法	第一个参数必须是实例,一般命名为self	                                可以访问实例的属性和方法,也可以访问类的属性和方法	    一般通过实例调用
    # 类方法	    使用装饰器@classmethod修饰,第一个参数必须是当前的类对象,一般命名为cls	可以访问类的属性和方法	                            类实例和类都可以调用
    # 静态方法	使用装饰器@staticmethod修饰,参数随意,没有self和cls	                不可以访问类和实例的属性和方法	                    实例对象和类对象都可以调用

    # 在面向对象的设计理念中,方法必定属于某个类,但这个方法可能不会访问 实例和类的任何属性或其他方法,对于这种方法,我们就应该把它设计成静态方法。
    # 一个方法会访问到类的属性,这个方法就不是某个实例 所特有的,而是整个类所拥有的一个方法,那么就需要把它设计成类方法。

    # 如果一个方法不访问实例的属性,但会访问类的属性和方法时,就可以设置成类方法。
    # 如果一个方法,既不会访问实例属性或方法,也不会访问类的属性或方法,方法里的都是有关逻辑性的代码,那么这种代码就可以设置成静态方法。

    pass


class People(object):

    country = 'cn'

    def __init__(self, name):
        self.name = name

    @classmethod
    def dance(cls):
        print('跳的是{}舞'.format(cls.country))

    @classmethod
    def dance_2(cls):
        print('dance_2() 开始执行')
        cls.dance()
        print('跳的是{}舞'.format(cls.country), '再跳一次')
        print('dance_2() 执行over')

    def sing(self):
        print('sing() 开始执行。。。')
        self.sing_2()
        print('{}-在唱歌'.format(self.name), '唱的是{}歌'.format(self.country))
        self.sing_one()
        self.sing_two('sing_two方法')
        self.dance()
        self.dance_2()
        print('sing() 执行over。。。')

    def sing_2(self):
        print('sing2() 不喜欢唱歌,但{}喜欢'.format(self.name))

    @staticmethod
    def sing_one():
        print('自己在唱歌')

    @staticmethod
    def sing_two(other: str):
        print('自己在唱歌,假装和{}在一起唱歌'.format(other))



if __name__ == '__main__':
    p = People('小王')
    p.dance()
    p.sing()
    p.sing_one()
    p.sing_two('小明')

    print()

    People.dance()
    # People.sing()           # TypeError: sing() missing 1 required positional argument: 'self'

    People.sing_one()
    People.sing_two('XiaoMing')

函数参数

https://docs.python.org/zh-cn/3.7/tutorial/controlflow.html#more-on-defining-functions

定义函数

定义函数的时候,若有参数,这该咋写?

  1. 位置参数

调用必传;传参时,按照位置 对应函数定义时的参数,顺序不能错;

  1. 默认参数 【键值对、必须指向 不变对象

调用非必传;传参时,若传递就使用 传递的值;没传递就使用 默认值;

  1. 不定长元组参数(*args)

调用非必传;加了一个星号的参数 *args ,这个形参可同时接受多个实参(必须使用 位置参数 传参,不然会报错) 这个参数的本质是一个元组;

出现在 *args 参数之后的任何形式参数都是 ‘默认参数’


def test_args(test, *args, name='zyooooxie', ad='csdn'):
    print('test值:{}'.format(test))
    print(name, '这是name的值')

    print(args)
    for a in args:
        print(a)
        
    print('剩下的是:{} 和 {}'.format(name, ad))


test_args(123, 789, '678zy', 6.222, ad='sd', name='zy')

  1. 不定长字典参数(**kwargs)

调用非必传;加了两个星号的参数 **kwargs,这个形参可同时接受多个实参(必须使用 默认参数传参,不然会报错) 这个参数的本质是一个字典;



def test_kwargs(test_num, *args, new='0000', name='zyooooxie', **kwargs):
    print('test数字:', test_num)
    print(name, '这是name的值')
    print('new的值:{}'.format(new))

    print(args)
    for a in args:
        print(a, end='--')

    print()

    print(kwargs)
    for k, v in kwargs.items():
        print(k, v, end='++')

    print()


test_kwargs(67890, '23ss', 'an', hh5='很好', hh1='哈哈', hh2='呵呵', hh3='嘿嘿', hh4='好好', new='1111', name='zy')


.在这里插入图片描述

函数调用时

Functions can also be called using keyword arguments of the form kwarg=value.

关键字参数不是一个出现在函数定义时的概念,而是一个出现在函数调用时的概念。

调用规则:

在函数调用中,关键字参数必须跟随在位置参数的后面。
传递的所有关键字参数必须与函数接受的其中一个参数匹配,它们的顺序并不重要。
不能对同一个参数多次赋值。

当存在一个形式为 **name 的最后一个形参时,它会接收一个字典,其中包含 除了与已有形参相对应的关键字参数以外 的所有关键字参数。 这可以与一个形式为 *name,接收一个包含 除了已有形参列表以外 的位置参数的 元组 的形参 组合使用 (*name 必须出现在 **name 之前)。

函数 实参的解包

https://docs.python.org/zh-cn/3.7/tutorial/controlflow.html#unpacking-argument-lists

函数调用时,一个星号可作用于所有的可迭代对象,称为迭代器解包操作,作为位置参数传递给函数;两个星号只能作用于字典对象,称之为字典解包操作,作为关键字参数传递给函数。

在这里插入图片描述

二进制序列类型 bytes、bytearray

官方文档: https://docs.python.org/zh-cn/3.7/library/stdtypes.html#binary-sequence-types-bytes-bytearray-memoryview

bytes 对象是由单个字节构成的不可变序列。
bytearray 对象是 bytes 对象的可变对应物。


def test_bytearray():
    # 使用 list(b) 将 bytearray 对象转换为一个由整数构成的列表

    a = bytearray(12)        # 如果 source 为整数,则返回一个长度为 source、以零值填充 的初始化数组;
    print(a)
    print(a[0])
    print(list(a))
    print(a.decode())

    # 如果 source 为字符串,则按照指定的 encoding 将字符串转换为字节序列;
    b = bytearray('123sss写123###', encoding='utf-8')
    print(b, '123sss写123###'.encode(), bytes('123sss写123###', encoding='utf-8'))
    print(list(b))
    print(b.decode())

    # 如果 source 为可迭代类型,则元素必须为[0 ,255] 中的整数;
    c = bytearray([int('1'), 2, 99])
    print(c, '初始的')
    c.append(123)       # 添加的元素
    print(c)
    c.append(87)
    print(c)
    c.append(65)
    print(c)
    c.extend(range(3))
    print(c)
    c.insert(3, 102)
    print(c)
    print(list(c))
    print(c.decode())

    # d = bytearray((22, 782, 92828))     # byte must be in range(0, 256)
    # print(d)

    e = bytearray()
    print(e)
    print(list(e))
    print(e.decode())

    f = bytearray(b'Hi!')   # 基本ASCII使用字符
    print(f)
    print(list(f))
    print(f.decode())

    g = bytearray(range(20))
    print(g)
    print(list(g))
    print(g.decode())


def test_bytes():

    # bytes() 返回一个新的“bytes”对象。
    # 字节串也叫字节序列,是不可变的序列;序列中的每个值的大小被限制为 0 <= x < 256
    # 可以使用 list(b) 将 bytes 对象转换为一个由整数构成的列表

    a = bytes(12)           # 指定长度的 以零值填充的 bytes 对象
    print(a)
    print(a[2])
    print(list(a))
    print(a.decode())       # 解码的值

    # bytes() 创建一个空的字节串 ,同b””
    b = bytes()
    print(b, type(b))
    print(list(b))
    print(b.decode())

    # bytes(整数可迭代对象) 用可迭代对象创建一个字节串
    c = bytes((1, 2, 33, 44))
    print(c)
    print(list(c))
    print(c.decode())

    c = bytes(range(7))
    print(c)
    print(list(c))
    print(c.decode())

    # bytes(字符串,encoding=’utf-8’) 转码
    d = bytes('xie写111222@@@', encoding='utf-8')
    # bytes(string,encoding) 等价于string.encode()
    print(d, 'xie写111222@@@'.encode())
    print(list(d))
    print(d.decode())

    print(d.replace(b'x', b'X'))
    print(d.replace(b'a', b'A'))        # 实际没有b'a'

    print(d.find(b'X'))
    print(d.hex())      # hex() 返回16进制表示的字符串
    

compile()

https://docs.python.org/zh-cn/3.7/library/functions.html#compile


def test_compile():
    # 将 source 编译成代码或 AST 对象。返回表达式执行结果。
    # source 可以是常规的字符串、字节串,或者 AST 对象; This can be string, byte string or AST module object.

    # mode 实参指定了编译代码必须用的模式。如果 source 是语句序列,可以是 'exec';如果是单一表达式,可以是 'eval';如果是单个交互式语句,可以是 'single'

    # 'exec': indicates compliation is intended for an entire Python module
    # 'single': indicates compilation is intended for a single statement
    # 'eval': indicates compilation is intended for a single expression

    # 在 'single' 或 'eval' 模式编译多行代码字符串时,输入必须以至少一个换行符结尾。在 'exec' 模式不再需要以换行符结尾

    # filename 实参需要是代码读取的文件名;如果代码不需要从文件中读取,可以传入一些可辨识的值(经常会使用 '<string>')
    a = compile(source='m=89\nprint("123123")\nprint(m)', filename='<string>', mode='exec')
    print(a)        # code object

    # A = compile(source='print("123123")\nprint(a)', filename='<string>', mode='eval')
    # print(A)        # SyntaxError: invalid syntax  可能是eval的原因

    code_str = 'x=3\ny=x+33\nprint("x+y的值是",x+y)'
    b = compile(code_str, '<string>', 'exec')
    print(type(b), b)
    exec(b)

    with open('123456.txt', 'r') as f:
        file_str = f.read()

    c = compile(source=file_str, filename='123456.txt', mode='exec')
    exec(c)


def test_compile2():
    # 缩进 要留意
    code_str = """
def fun():
    list1 = [1, 2, 3]
    print(list1)
    list1.append('try')
    print(list1)
    list1.extend(['zyooooxie', 'csdn'])
    print(list1)
    return list1
fun()"""

    a = compile(code_str, filename='<string>', mode='exec')
    exec(a)

    test_list = [218, 238, 248, 228]

    code = """
def fun2(some_list):
    print(some_list[1],some_list[2],some_list[3])
fun2(test_list)
fun2(code_str)

    """
    b = compile(code, filename='<string>', mode='exec')
    exec(b)
    # fun2(code_str) code_str是str,非list


def test_compile3():

    # file内 定义的变量可能有问题: NameError: name 'myfn' is not defined

    with open('import_py.py', 'r', encoding='utf-8') as f:
        src = f.read()

        c = compile(src, filename='import_py.py', mode='exec')
        exec(c)

    with open('import_py2.py') as f:
        contents = f.read()

    code_obj = compile(contents, 'import_py2.py', 'exec')
    exec(code_obj)

123456.txt

x=123
y=456
print(x*y)

@File: import_py.py


def test():
    import time         # 写 最上面会报错,time没定义

    print(time.time())


test()

@File : import_py2.py

def myfn(mydict):
    import json

    return json.dumps(mydict)


def myfn2():
    return myfn({
    
    "x": 30})


print(myfn2())

本文链接:https://blog.csdn.net/zyooooxie/article/details/108181446

交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie

おすすめ

転載: blog.csdn.net/zyooooxie/article/details/108181446