【无标题】

超算三轮AI方向考核

1.Python知识点学习

1.函数式编程

案例1_二次方程求根

python

import math
def quadratic(a, b, c):
    delta = b ** 2 - 4 * a * c
    m = -b/(2 * a)
    if delta > 0:
        n = math.sqrt(delta)/(2 * a)
        return m+n,m-n 
    elif delta == 0:
        return m,m
    else:
        n = math.sqrt(-delta)/(2 * a)
        print('(%.1f + %.1fi, %.1f - %.1fi)'%(m,n,m,n))
x1 = quadratic(2,3,1)
x2 = quadratic(1,3,-4)
print(x1, x2)
x3 = quadratic(1,1,4) 

#(-0.5, -1.0)
 (1.0, -4.0)
(-0.5 + 1.9i, -0.5 - 1.9i) 
案例2_汉诺塔问题(三柱)

涉及递归函数,将复杂问题简单化

count = 1
def move(n, a, b, c): #  n层数,所在塔,中介塔,目标塔
    global count # 全局变量
    if n == 1:
        print('step', count, ':', a, '-->', c)
        count = count + 1
    else:
        move(n-1, a, c, b) # 上部n-1个移动到b
        move(1, a, b ,c) # 底下一个移动到c
        move(n-1, b, a, c) # b中n-1个移动到c
move(3, 'a', 'b', 'c')
step 1 : a --> c
step 2 : a --> b
step 3 : c --> b
step 4 : a --> c
step 5 : b --> a
step 6 : b --> c
step 7 : a --> c

案例3_去字符串首尾空格并输出
def trim(s):
    l = len(s)
    if l == 0:
        return s
    if l > 0:
        l1 = l
        for i in range(l):
            if s[i] != ' ':
                s1 = s[i:]
                break
        l2 = len(s1)
        while l2 > 0:
            if s1[l2-1] != ' ':
                s2 = s1[:l2]
                break
            l2 = l2 - 1

    return s2
str = '  abc  '
print(str)
s = trim(str)
print(s)
  abc  
abc
循环1删去头字符串,循环2删去尾字符串
用到切片[i:]表示获得从第i位字符到最后一位,[:l2]表示获得从第一位到第l2-1位字符```
案例4_字符串改浮点数
def strfloat(s):
    i = 0
    j = 0
    digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    while s[i] != '.':
        j = j * 10 + digits[s[i]]  # 先算出整数部分
        i += 1
    i += 1
    m = 10
    while i < len(s):
        j = j + digits[s[i]] / m  # 算出小数部分
        m = 10 * m
        i = i + 1
    return j
t = strfloat('123.456')
print(t)  # 123.456

2.列表生成式

格式
variable    =    [out_exp    for    out_exp    in    input_list    if    out_exp    ==    2]
案例1_数组列表筛选

将3x3的矩阵li1转化成一个数组(列表),且使该数组中仅仅包含偶数:

li1 =[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

li1 =[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print([item2 for item1 in li1 for item2 in item1 if item2 % 2 == 0]) # [2, 4, 6, 8]
案例2_英文字符大小写转换
#要求筛选出英文字符并转换成小写
L = ['Hello', 'World', 18, 'Apple', None]
print([s.lower() for s in L if isinstance(s, str)])

运行结果
['hello', 'world', 'apple']
案例3_杨辉三角
def triangles():
    L = [1]
    while True:
        yield L  # 关键字yield的使用
        L = [1] + [L[i]+L[i+1]for i in range(len(L) - 1)] + [1]

t = triangles()
for i in range(10):
    print(next(t))  # next() 用于生成下一个结果,注意需要使用变量t,而不能直接next(triangles)
#输出结果

[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]

3. 高阶函数

只要满足下面的任意一个条件就是高阶函数

1、一个函数的函数名作为参数传给另外一个函数
2、一个函数返回值(return)为另外一个函数(返回为自己,则为递归)

1.参数为函数名_简单案例
def add(x, y, f):
    return f(x) + f(y)
print(add(1, -5, abs))  # 取二者绝对值并相加,传入的参数为函数abs
2.函数返回值为另一个函数
def func():
    print("定义一个普通函数")
    
def high_level(func):
    print("定义一个高阶函数")
    return func
    #  return func() 这个是直接返回函数调用,递归函数就是如此
    
res = high_level(func)
#高阶函数返回函数之后在调用func函数
res()
#结果

注意要高阶函数的返回值为函数,则必须要把函数作为参数传入

3.内置高阶函数

1、map
2、filter
3、reduce:是functools模块中的函数,需要导入
4、sorted

1.map

map函数接收的是两个参数,一个是函数名,另外一个是序列,其功能是将序列中的数值作为函数的参数依次传入到函数值中执行,然后再返回到列表中。返回值是一个迭代器对象

案例
def func(x):
    return x**2
    
print(list(map(func, [2,3,4,5])))  # [4, 9, 16, 25]
2.filter

filter函数也是接收一个函数和一个序列的高阶函数,其主要功能是过滤。其返回值也是迭代器对象

案例1
num = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(filter(lambda x: x % 2 == 0, num)))
 # [2, 4, 6, 8]
案例2_回文序列
def is_palindrome(n):
   l = n 
   x = 0
   while l != 0:
       a = l % 10
       x = x * 10 + a
       l //= 10
   return  n == x
print(list(filter(is_palindrome, range(1, 200))))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
3.reduce

reduce函数也是一个参数为函数,另一个参数为可迭代对象 Iterable Object(eg: list列表)。,其返回值为一个值而不是迭代器对象,故其常用与叠加、叠乘等

案例
from functools import reduce  # 需要先导入模块
def fn(x, y):
    return x * 10 + y
print(reduce(fn, [1, 3, 5, 7, 9]))
4.sorted

Python内置的sorted()函数就可以对list进行排序:

>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
1
2

此外,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
案例1_排序
def by_name(t):
    return t[0].upper()
def by_score(t):
    return t[1]
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
L2 = sorted(L, key=by_name)  # 按姓名
print(L2)
L3 = sorted(L, key=by_score, reverse = True)  # 按分数
print(L3)
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
案例1_字符串转化为整型
from functools import reduce
def fn(x, y):
    return x * 10 + y
def charnum(s):
    digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    return digits[s]
print(reduce(fn, map(charnum, '13579')))  # 13579

整合

from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}  # 全局变量
def strint(s):
    def fn2(x, y):
        return x * 10 + y
    def char2num(s):
        return DIGITS[s]
    return reduce(fn2, map(char2num, s))
print(strint('13579'))  # 13579
案例2_名字规范化
from functools import reduce
def normalize(name):
    return name[0].upper() + name[1:].lower()
L = ['adam', 'LISA', 'barT']
print(list(map(normalize, L)))  # ['Adam', 'Lisa', 'Bart']
案例3_求积
def prod(l):
    def multiply(x, y):
        return x * y
    return reduce(multiply, l)
L = list(range(1,11))
print(prod(L))  # 3628800

4.迭代器和生成器

1.迭代器

迭代是访问集合元素的一种方式,在Python中,迭代是通过 for … in … 语句来完成的。

在Python中,可直接作用于 for循环 的对象都称为可迭代对象(Iterable),而可以作用于 for循环 的数据类型有以下两类:

一类是集合数据类型,比如常见的 str、list、tuple、dict、set
另一类是生成器(generator),包括生成器带 yield 的生成器函数
注意:可迭代对象不一定是迭代器,但迭代器一定是可迭代对象。他们是包含关系。

str、list、tuple、dict、set 都是可迭代对象(Iterable),但它们并不是迭代器(Iterator),我们可以通过迭代器中的iter()函数把这些可迭代对象(Iterable) 变成 迭代器(Iterator)。

基本方法:iter()、next()

使用iter()创建一个迭代器后,就可以通过 next() 获取迭代器的下一个值,如果通过 next() 不断调用并返回下一个值,那么等到最后没有下一个值了,就会抛出异常:StopIteration

2.生成器
生成器函数

在Python中,普通函数一般通过 return 来返回一个值,当我们使用关键字 *yield *来返回值,那么这个带有 yield 的函数就变成了生成器函数。

案例_打印1000以内的素数(埃氏筛法)
def _odd_iter():
    n = 1
    while True:
        n += 2
        yield n
def _not_divisible(n):
    return lambda x: x % n > 0
def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it) # 构造新序列

 # 打印1000以内的素数:
for n in primes():
    if n < 1000:
        print(n,end = ' ')
    else:
        break
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 
157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 
313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 
487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 
661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 
859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997

5.闭包(返回函数)

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax =ax + n
        return ax
    return sum
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print(f1 == f2) # 当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数,调用结果互不影响--'  闭包  '程序结构
# 内部的局部变量还被新函数引用,返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
# 循环举例
def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i * i
        fs.append(f)
    return fs
# f1, f2, f3 = count()
# 结果全部都是9!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
# 如果一定要引用循环变量,方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
def count1():
    def f1(j):
        def g():
            return j * j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f1(i)) # # f(i)立刻被执行,因此i的当前值被传入f()
    return fs

# f1, f2, f3 = count1()
# >>>f1()
# 1
# >>>f2()
# 4
# >>>f3()
# 9
# 缺点:代码太长
# nonlocal
# 使用闭包,就是内层函数引用了外层函数的局部变量。如果只是读外层变量的值,我们会发现返回的闭包函数调用一切正常:
def inc():
    x = 0
    def fn():
        # 仅读取x的值:
        return x + 1
    return fn

f = inc()
print(f()) # 1
print(f()) # 1

def inc1():
    x = 0
    def fn1():
        nonlocal x
        x = x + 1
        return x
    return fn1

f1 = inc()
print(f1()) # 1
print(f1()) # 2

原因是x作为局部变量并没有初始化,直接计算x+1是不行的。但我们其实是想引用inc()函数内部的x,所以需要在fn()函数内部加一个nonlocal x的声明。
加上这个声明后,解释器把fn()的x看作外层函数的局部变量,它已经被初始化了,可以正确计算x+1。
使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量 ’ 不是当前函数的局部变量 ’ 。

案例_递增整数
def createCounter():
    x = 0
    def counter():
       nonlocal x
       x += 1
       return x
    return counter
counter1 = createCounter()
for i in range(5):
    print(counter1()) 
1
2
3
4
5

6.匿名函数 lambda

关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

f = lambda x: x * x
print (f(8))

同样,也可以把匿名函数作为返回值返回,比如:

def build(x, y):
    return lambda: x * x + y * y

7.装饰器

装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

案例1
import functools

def log(text):
    def decorator(func):  # 给fn函数加上装饰器
        @functools.wraps(func)
        def wrapper(*args, **kw):  # 参数可以是任意的
            print('%s %s():' % (text, func.__name__))  # 打印函数名
            return func(*args, **kw)  
        return wrapper # 返回值为函数 不用加括号
    return decorator

@log('execute')  
def now():
    print('2015-3-25')
t = now()

结果

execute now():
2015-3-25
案例2
# 设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间
import time, functools

def metric(fn):
    @functools.wraps(fn)   # 保留原始函数名称
    def wrapper(*args, **kw):
        begin = time.time()
        res = fn(*args, **kw)
        end = time.time()
        print('%s executed in %s ms' % (fn.__name__, round(end - begin, 3)))  # 保留三位小数
        return res
    return wrapper

@metric  # 给fast函数加装饰器
def fast(x, y):
    time.sleep(0.0012)
    return x + y;
  
f = fast(11, 22)
print(f)

@metric  # 给slow函数加装饰器
def slow(x, y, z):
    time.sleep(0.1234)
    return x * y * z;
s = slow(11, 22, 33)
print(s)

运行结果

fast executed in 0.009 ms
33
slow executed in 0.127 ms
7986
案例3
import functools
def log3(*text):# decorator需要传参数,再加一层嵌套
	def decorator(func):
		@functools.wraps(func)
		def wrapper(*args, **kw):
			print('%s beigin call, log text:%s' % (func.__name__, text))
			f = func(*args, **kw)
			print('%s end call, log text:%s' % (func.__name__, text))
			return f
		return wrapper
	return decorator

@log3() # 要加括号
def f1():
	print('f1 execute')

@log3('execute')
def f2():
	print('f2 execute')

t1 = f1()

t2 = f2()

运行结果

f1 beigin call, log text:()
f1 execute
f1 end call, log text:()
f2 beigin call, log text:('execute',)
f2 execute
f2 end call, log text:('execute',)

8.偏函数

偏函数
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:

int(‘12345’) 12345
但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:
创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数
int(‘12345’, base=8) 5349(八进制转十进制)

import functools
int2 = functools.partial(int, base = 2)
print(int2('1000000')) # 相当于:kw = { 'base': 2 }int('1000000', **kw)

9.面向对象

1.类

是用来描述具有相同属性和方法的对象的集合,定义了该集合中每个对象所共有的属性和方法,对象则是类的实例;

class(类)的外部函数叫做函数function,类的内部函数叫做方法method

在类的创建过程中需要注意的如下事项:

1.类变量:在创建的类中会定义一些变量,我们把这些变量叫作类变量,类变量的值在这个类的所有实例之间是共享的,同时内部类或者外部类也能对这个变量的值进行访问。
2.init():是类的初始化方法,我们在创建一个类的实例时 就会调用一次这个方法。
3.self:代表类的实例,在定义类的方法时是必须要有的,但是在调用时不必传入参数。

示例1
class MessageInfo:  # 创建类
    def send_email(self, to_email):
        msg = "给{}的{}发送一个邮件".format(self.name, to_email)
        print(msg)
    
    def send_dingding(self, to_email):
        msg = "给{}发送一个钉钉".format(to_email)
        print(msg)

    def send_wechat(self, to_email):
        msg = "给{}发送一个微信".format(to_email)
        print(msg)


 #  创建一个MessageInfo类的对象(实例化)
obj1 = MessageInfo()
obj1.name = "青海"
obj1.send_email("x1")


obj2 = MessageInfo()
obj2.name = "江西"
obj2.send_email("x2")

运行结果

给青海的x1发送一个邮件
给江西的x2发送一个邮件
示例2
class MessageInfo:
    def __init__(self, city):  # 创建对象时执行,初始化一些值
        self.city = city
        self.company = "联通"  # 静态变量,类变量
    def send_email(self, to_email):
        msg = "给{}的{}发送一个邮件".format(self.city, to_email)
        print(msg)


obj1 = MessageInfo("江西")
obj1.send_email("x1")

obj2 = MessageInfo("青海")
obj2.send_email("x2")

运行结果

给江西的x1发送一个邮件
给青海的x2发送一个邮件
应用场景1_数据封装

需要参数反复传递的,将数据封装到创建的对象中

示例

class Foo:
    def __init__(self, a1, a2, a3, a4):
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3
        self.a4 = a4

    def f1(self):
        print(self.a1, self.a2, self.a3, self.a4)
    def f2(self):
         print(self.a1, self.a2, self.a3, self.a4)
    def f3(self):
         print(self.a1, self.a2, self.a3, self.a4)
obj3 = Foo(11, 22, 33, 44)
obj3.f1()   # 11 22 33 44 
obj3.f2()   # 11 22 33 44 
obj3.f3()   # 11 22 33 44 
案例
# 做数据的封装(定义类用对象来封装数据) 
class UserInfo:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show(self):
        message = "我的姓名:{},今年{}岁".format(self.name, self.age)
        print(message)

user_list = []  # 创建空列表,用于存放实例对象

while True:
    name = input("姓名:")
    if name == "-1":  # 循环出口
        break

    age = input("年龄:")

    info = UserInfo(name, age)
    user_list.append(info)


for item in user_list:
    item.show()
    ```
    运行结果
    ```
    姓名:dch
年龄:19
姓名:cyy
年龄:19
姓名:lucy
年龄:20
姓名:cindy
年龄:18
姓名:-1
我的姓名:dch,今年19岁
我的姓名:cyy,今年19岁
我的姓名:lucy,今年20岁
我的姓名:cindy,今年18岁
应用场景2_类型多,用于归类(警察与恐怖分子)
class Police:
    def __init__(self, name, age, hit_points):
        '''警察'''
        self.name = name
        self.age = age
        self.hit_points = hit_points

    def catch(self):
        '''抓小偷'''
        self.hit_points = self.hit_points + 100

    def smoking(self):
        '''抽烟'''
        self.hit_points = self.hit_points - 50

    def shoot(self, target):
        '''射击'''
        self.hit_points  = self.hit_points - 10
        target.hit_points =target.hit_points - 200


class Terriorist:
    '''恐怖分子'''
    def __init__(self, name, hit_points):
        self.name = name
        self.hit_points = hit_points

    def shoot(self, user):
        '''射击'''
        user.hit_points = user.hit_points - 200

    def strafe(self, *user_list):
        '''扫射'''
        for user in user_list:
            user.hit_points = user.hit_points - 200

    def bomb(self, *user_list):
        '''炸弹'''
        for user in user_list:
            user.hit_points = user.hit_points - 300

        self.hit_points = self.hit_points - 100

# 创建两个警察,三个匪徒
p1 = Police("lipan", 22,1000)
p2 = Police("yujuan",25, 800)

t1 = Terriorist("zhangsan", 2000)
t2 = Terriorist("lisi", 2000)
t3 = Terriorist("wangwu", 2000)

# 警察和匪徒火拼, ->至少五个 -> 分析每一个步骤战斗值的变化

p1.smoking()
p2.catch()

t1.bomb(p1, p2)
t2.strafe(p1, p2, t1)

print(p1.hit_points,p2.hit_points, t1.hit_points, t2.hit_points, t3.hit_points)
# 运行结果 450 400 1700 2000 2000
2.继承
示例1
class Base:  # 父类或者基类
    pass

class Son(Base):  # 子类
    pass
class TCPServer:  # 创键TCPSever类
    def f1(self):
        print("TCPServer")

class ThreadingMixIn:  # 创键ThreadingMixIn类
    def f1(self):
        print("ThreadingMixIn")

class ThreadingTCPServer(ThreadingMixIn, TCPServer):  # 子类优先继承第一个父类
    def run(self):
        print('before')
        self.f1() # 先在括号里左边的类找f1(),没有的话右边
        print('after')

obj4 = ThreadingTCPServer()  # 实例化
obj4.run()

# before
# ThreadingMixIn
# after
示例2
class TCPServer:
    def f1(self):
        print("TCPServer")

    def run(self):  # self = obj
        print('before')
        self.f1() 
         # self = obj -> obj.f1() -> 回到ThreadingTCPServer类
        print('after')

class ThreadingMixIn:
    def f1(self):
        print("ThreadingMixIn")

class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
    # 该类里没有f1(),所以在括号左边的类里找
    pass

obj5 = ThreadingTCPServer()
obj5.run()  # run函数在TCPSever类中

# before
# ThreadingMixIn
# after
3. 多态
1.成员和称呼
# 成员和称呼
class Info:
    city = "上海"
    # 静态变量,类变量(省内存)
    
    def __init__(self, name):
    # 变量/字段 ->实例变量
        self.name = name
    
    # 绑定方法  至少有一个self参数,执行时先创建对象,再由对象触发来执行
    def send(self):
        pass

    # 静态方法  
    #  可以有任意个参数 + @staticmethod , 可以通过类执行触发执行,例如: Info.get_data(); #
    #  对象也能触发执行:obj = Info()  obj.send()
    # 一般不需要封装的数据时使用
    @staticmethod
    def get_data(a1, a2, a3):
        pass

    # 类方法 定时,至少有一个cls参数,执行时可以同类执行执行,例如:Info.fetch(12)    -> cls是类名
    # 对象也能触发执行,obj = Info()  obj.fetch(333)   -> cls是类名
    @ classmethod
    def fetch(cls, a1):
        pass

print(Info.city)  # 上海

v1 = Info("青海")
print(v1.name)  # 青海

print(v1.city)  # 上海
2.属性
class Foo:  
    @property
    def d1(self):
        return 123

obj = Foo()
print(v1 = obj.d1) #调用大小写不用括号
案例
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def d1(self):  # 只有一个参数self
        return "{}-{}".format(self.name, self.age)

    @d1.setter
    def d1(self, value):
        self.age = value

    @d1.deleter
    def d1(self):
        self.age = 0

obj6 = Foo("root", 10)
print(obj6.d1)  # 不是封装的数据,是临时计算并返回的结果,不需要加括号
print(obj6.name)
print(obj6.age)

obj6.d1 = 123 # 触发setter方法
print(obj6.d1)
del obj6.d1 # 触发deleter方法
print(obj6.d1)

运行结果

root-10
root
10
root-123
root-0  # 删除后值人为赋为0,不懂和setter有什么区别???
属性访问

getattribute
getattr
setattr
delattr

class C:
    def __getattribute__(self, item):  # __getattribute__(self, name):定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用__getattr__)
        print('__getattribute__')
        return super().__getattribute__(item)

    def __getattr__(self, item):  # __getattr__(self, name): 定义当用户试图获取一个不存在的属性时的行为
        print('__getattr__')

    def __setattr__(self, key, value):  # __setattr__(self, name, value):定义当一个属性被设置时的行为
        print('__setattr__')
        super().__setattr__(key, value)

    def __delattr__(self, item):  # __delattr__(self, name):定义当一个属性被删除时的行为
        print('__delattr__')
        super().__delattr__(item)


c = C()
c.x
# __getattribute__
# __getattr__

c.x = 1
# __setattr__

del c.x
# __delattr__
扩展

扩展

class Foo:
    def __init__(self, name,age):
        self.name = name
        self.age = age

    def getx(self):
        return 345
    def setx(self, value):
        pass
    def delx(self):
        pass

    x = property(getx, setx, delx)
    
obj7 = Foo("root", 10)

obj7.x       # 会先执行property括号内的第一个函数getx
obj7.x = 999 # 此时对应property括号内的第二个函数
del obj7.x    # 对应执行第三个
4.特殊成员
1.__init__, 初始化方法, __new__,构造方法
class Fuu:
    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        # 创建的空对象
        obj8 = object.__new__(cls)
        return obj8


# 1.创建空对象 obj = 对象(内容是空)   new,创建对象
# 2.执行init方法 obj.__init__("xxx")    init,初始化

obj8 = Fuu("xxx")
2.__call__方法
class Fii:
    def __init__(self, name):
        self.name = name
        self.age = 19

    def __call__(self, *args, **kwargs):
        print(11111)

obj9 = Fii("eric")
print(obj9.name)  # eric
print(obj9.age)  # 19

obj9()  # 调用__call__方法 ->11111
3.dict方法

# dict方法 获取类里边的成员,并用字典的形式返回

class Faa:
    city = "上海"

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

    def __str__(self):
        return "{}:{}".format(self.name, self.age)

    def __getitem__(self, item):
        return 999

    def __setitem__(self, key, value):
        print(key, value)

    def __delitem__(self, key):
         print(key)

    def __enter__(self):
        print("进来了")
        return "吴佩琪"

    def __exit__(self, exc_tpe, exc_val, exc_tb):
        print("出去了")
        return "吴佩琪"

    def __add__(self, other):
        return self.age + other.age
        
obj10 = Faa("张开")
print(obj10.__dict__)
# {'name':'张开', 'age': 19}
# __str__方法

print(obj10) # 此时会调用__str__函数

# __getitem__,__setitem__,__delitem__ 对象的切片索引等方法

print(obj10[0])
obj10[2] = “哈哈哈哈”
del obj10[777]

# __enter__, __exit__方法 开始和结束

with obj10 as f: # f就是返回的值
print(111)

运行结果

 张开:19
 999
2 哈哈哈哈
777
进来了
111
出去了
4.运算方法
__add__方法
# __add__方法  加减乘粗大于小于等于都可以 类里面要定义相关方法

f1 = Faa("张三")
f2 = Faa("李四")
data = f1 + f2 # f1.__add__(f2)
print(data)  # 38
其他运算

‘’’
add(self, other)定义加法的行为:+
sub(self, other)定义减法的行为:-
mul(self, other)定义乘法的行为:*
truediv(self, other)定义真除法的行为:/
floordiv(self, other)定义整数除法的行为://
mod(self, other) 定义取模算法的行为:%
divmod(self, other)定义当被 divmod() 调用时的行为
divmod(a, b)把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
pow(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
lshift(self, other)定义按位左移位的行为:<<
rshift(self, other)定义按位右移位的行为:>>
and(self, other)定义按位与操作的行为:&
xor(self, other)定义按位异或操作的行为:^
or(self, other)定义按位或操作的行为:|
‘’’

反运算魔方方法

‘’’
反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔法方法多了一个“r”。当文件左操作不支持相应的操作时被调用。

radd(self, other)定义加法的行为:+
rsub(self, other)定义减法的行为:-
rmul(self, other)定义乘法的行为:*
rtruediv(self, other)定义真除法的行为:/
rfloordiv(self, other)定义整数除法的行为://
rmod(self, other) 定义取模算法的行为:%
rdivmod(self, other)定义当被 divmod() 调用时的行为
rpow(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
rlshift(self, other)定义按位左移位的行为:<<
rrshift(self, other)定义按位右移位的行为:>>
rand(self, other)定义按位与操作的行为:&
rxor(self, other)定义按位异或操作的行为:^
ror(self, other)定义按位或操作的行为:a + b

这里加数是a,被加数是b,因此是a主动,反运算就是如果a对象的__add__()方法没有实现或者不支持相应的操作,那么 Python 就会调用b的__radd__()方法。

【例子】

class Nint(int):
    def __radd__(self, other):
        return int.__sub__(other, self) # 注意 self 在后面

a = Nint(5)
b = Nint(3)
print(a + b)  # 8
print(1 + b)  # -2

‘’’

‘’’

增量赋值运算符

iadd(self, other)定义赋值加法的行为:+=
isub(self, other)定义赋值减法的行为:-=
imul(self, other)定义赋值乘法的行为:*=
itruediv(self, other)定义赋值真除法的行为:/=
ifloordiv(self, other)定义赋值整数除法的行为://=
imod(self, other)定义赋值取模算法的行为:%=
ipow(self, other[, modulo])定义赋值幂运算的行为:**=
ilshift(self, other)定义赋值按位左移位的行为:<<=
irshift(self, other)定义赋值按位右移位的行为:>>=
iand(self, other)定义赋值按位与操作的行为:&=
ixor(self, other)定义赋值按位异或操作的行为:^=
ior(self, other)定义赋值按位或操作的行为:|=

一元运算符

neg(self)定义正号的行为:+x
pos(self)定义负号的行为:-x
abs(self)定义当被abs()调用时的行为
invert(self)定义按位求反的行为:~x

‘’’

5.对象之间的嵌套
# 对象之间的嵌套

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

s1 = Student("吴佩琪",22)

s2 = Student("张开", 12)

s3 = Student("李四", 32)

s4 = Student("王五", 16)


class Cls:
    def __init__(self, title):
        self.stu_list = []
		self.title = title
    def add(self, ele):
        self.stu_list.append(ele)

    def show_all_stu(self):
        for item in self.stu_list:
            print(item.name, item.age)

c1 = Cls("三年级")
c2 = Cls("五年级")

c1.stu_list.append(s1)
c1.stu_list.append(s2)

c1.add(s4) # 调用Cls类中的add方法,等价于直接写 c1.stu_list.append(s4) 
c2.add(s3)

print(c1.stu_list[0].name) # 吴佩琪
print(c1.stu_list[1].name) # 张开

class School:
    def __init__(self, city):
        self.city = city
        self.cls_list = []

sh = School("上海")
jx = School("江西")

sh.cls_list.append(c1)
jx.cls_list.append(c2)

sh.city # 上海
sh.cls_list[0].title # 三年级
sh.cls_list[0].stu_list # [s1对象,s2对象]
sh.cls_list[0].stu_list[0].name # 吴佩琪
sh.cls_list[0].stu_list[0].age # 22


10.模块(后续再补充)

1.自定义模块
2.内置模块

2.考核内容

1.列表生成式

'''
(1) 10,20,30,40,50,60
(2) 1,4,9,16,25,36,49
(3) 10,-20,30,-40,50,60
(4) 10,30,50(要求在 1 的基础上进行过滤)
(5) 打印乘法口诀表 (一行完成)
'''

List1 = [x for x in range(10, 61, 10)]

print(List1)

List2 = [y ** 2 for y in range(1, 8)]

print(List2)

List3 = [(-1) ** (i - 1) * i * 10 for i in range(1, 7)]

print(List3)

List4 = list(filter( lambda x: x / 10 % 2 == 1, List1))

print(List4)

# 九九乘法表

List5 = '\n'.join([' '.join([f'{j}*{i}={i*j}'for j in range(1,i+1)])for i in range(1,10)])
 
print(List5)

2.完成计时器对象,完成如下定义

提示:该对象的实例有一个列表,start 开始记录时间,每次 stop 将 (现在的时间-start 的时间)


import math
import time
import numpy as np
import torch

class Timer:
    '''记录多次运动时间'''
    def __init__(self):
        self.time = times = []

    '''启动计时器 '''
    def start ( self ):
        self.tik = time.time()

    def stop ( self ):
        '''停止计时并将时间记录在列表中'''
        self.time.append(time.time() - self.tik)
        return self.time[-1]

    def avg ( self ):
        ''' 返回平均时间。'''
        return sum(self.time) / len(self.time)

    def sum ( self ):
        '''返回时间总和。'''
        return sum(self.time)
    
    def cumsum ( self ):
        ''' 返回累计时间。'''
        return np.array(self.time).cumsum().tolist()
    
timer = Timer()
timer.start()

List1 = [x for x in range(10, 61, 10)]

print(List1)

List2 = [y ** 2 for y in range(1, 8)]

print(List2)

List3 = [(-1) ** (i - 1) * i * 10 for i in range(1, 7)]

print(List3)

List4 = list(filter( lambda x: x / 10 % 2 == 1, List1))

print(List4)

n = 10000
a = torch.ones(n)
b = torch.ones(n)

d = a + b

t = f'{timer.stop():.5f} sec'

print(t)  


运行结果

[10, 20, 30, 40, 50, 60]
[1, 4, 9, 16, 25, 36, 49]
[10, -20, 30, -40, 50, -60]
[10, 30, 50]
0.01400 sec
线程 'MainThread' (0x1) 已退出,返回值为 0 (0x0)。

程序“python.exe”已退出,返回值为 0 (0x0)。

时间精度不够,结果一直是0.00000 sec
可以优化为time.time() -> time.perf_counter()

# 该对象的实例有一个列表,start 开始记录时间,每次 stop 将 (现在的时间-start 的时间) 添加在列表中并将间隔的时间返回

import math
import time
import numpy as np
import torch

class Timer:
    '''记录多次运动时间'''
    def __init__(self):
        self.time = times = []

    '''启动计时器 '''
    def start ( self ):
        self.tik = time.perf_counter()

    def stop ( self ):
        '''停止计时并将时间记录在列表中'''
        self.time.append(time.perf_counter() - self.tik)
        return self.time[-1]

    def avg ( self ):
        ''' 返回平均时间。'''
        return sum(self.time) / len(self.time)

    def sum ( self ):
        '''返回时间总和。'''
        return sum(self.time)
    
    def cumsum ( self ):
        ''' 返回累计时间。'''
        return np.array(self.time).cumsum().tolist()
    
timer = Timer()
timer.start()



n = 10000
a = torch.ones(n)
b = torch.ones(n)

d = a + b

t = f'{timer.stop():.5f} sec'

print(t)


运行结果

0.01279 sec

进程已结束,退出代码0

3.完成累加器 Accumulator 类

Accumulator 是一个实用程序类,用于对多个变量进行累加; 提示:例如定义 n=2
的累加器 a,其会定义一个大小为 2 的列表 [0,0]; 调用 a.add(2,3) 之后其列表的值
对应累加为 [2,3]; a[idx] 则返回列表对应的索引的值; reset 重置这个列表为全零
[0,0]

class Accumulator :
    """ 在`n` 个变量上累加。"""
    def __init__ ( self , n):
        self.data = [0.0] * n  #  创建n个空间且全部初始化为0.0
        print(self.data)
    
    def add ( self , * args ):
        for x, y in zip(self.data, args):
            print(x, y)  # 分别把累加前的两个数据列出来
        self.data = [a + float(b) for a, b in zip(self.data, args)]  # 把原来类中对应位置的data和新传入的args做a+float(b)的操作并赋给该位置的data,达到累加的效果
        print(self.data)
    
    def reset ( self ):
        self.data = [0.0] * len(self.data)  # 重新设置空间大小并初始化

    def __getitem__ ( self , idx ):  # 取操作
        return self.data[idx]

测试一下

a = Accumulator(4) # [0.0, 0.0, 0.0, 0.0]
print(a[2])  # 0.0
a.add(2,5,8,2) # 0.0 2, 0.0 5, 0.0 8, 0.0 2 -> [2.0, 5.0, 8.0, 2.0]
print(a[2]) # 8.0
a.add(1,23,4)  # 2.0 1, 5.0 23, 8.0 4 -> [3.0, 28.0, 12.0]
print(a[2])  # 12.0

4.完成一个斐波那契数生成函数 (生成器)

f = fib() 可以不断调用 next(f) 并不断返回下一个值

def fib():
    x, y = 0, 1  # 赋初始值
    
    while True:
        yield y   # 每次只获取y的值
        x, y = y, x + y  

fi = fib()  # 必须用变量而不能直接用fib,next(fib)只能获得1,因为每次都从头调用
for i in range(10):  # 可用循环一次性获取到需要的数据
    print(next(fi))

5.龙珠计划 python 训练营链接,完成 Task5 测试。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值