一、学习目标:
(进度:3/3)
内容链接:
https://tianchi.aliyun.com/specials/promotion/aicamppython?spm=5176.19782939.J_5614344200.2.3ad4564b61mfN0
- 这次任务的内容在之前学的时候就感觉学的不是很好,这次主要是复健+补充学习。
本次任务分三天学习
二、学习内容:
1. 函数
- 可变参数:即在形参的前面加上*号,能够接受任意多个参数,将传入的参数自动存放入元组
- 关键词参数:即在形参前面加上**号,即能接受多个参数(接收类似于a=1这种样子,关键词参数会自动将传入的这种参数变成字典的样子)
- 命名关键词参数:这是对于出阿鲁参数的名有限制,具体看代码来理解
def student(name,age,*,sports):
print(name,age,sports)
#这里的sports前面加上了*号,也就是命名关键词参数了,只接受sports关键词名传入的参数,
#若是传入像score=98这种就会发生报错,因为我对关键词名进行了限制
- 参数组合的时候注意放置的位置,如(位置参数,默认参数,可变参数,关键词参数)或者(位置参数,默认参数,命名关键词参数,关键词参数)
- nonlocal:用在外部嵌套了函数,并且要使用外部函数的变量上。
def nonlocal_test():
count=0
def tet2():
nonlocal count
count+=1
return count
return test2
val=nonlocal_test()
print(val()) # 1
- 闭包一般返回的是函数,具体见下面代码解释
def make_counter(init):
counter = [init]
def inc(): counter[0] += 1
def dec(): counter[0] -= 1
def get(): return counter[0]
def reset(): counter[0] = init
return inc, dec, get, reset
inc, dec, get, reset = make_counter(0)
inc()
inc()
inc()
print(get()) # 3
dec()
print(get()) # 2
reset()
print(get()) # 0
def funX(x):
def funY(y):
return x * y
return funY
i = funX(8) 也就是i也变成了函数,需要传入向形参y传入参数
print(type(i)) # <class 'function'>
print(i(5)) # 40
- 关于匿名函数,里面的参数前面也可以加上*号接收多个参数,例如下面的例子:
func=lambda *args: sum(args)
print(func(1,2,3,4,5) #15
- filter:一般是用于过滤,过滤掉不符合条件的参数
odd=lambda x: x%2==1
teplist=filter(odd,(1,2,3,4,5,6,7,8,9))
print(list(teplist)) #[1, 3, 5, 7, 9]
- 与filter相反的是map函数,能够根据提供的函数对指定序列操作。
m1=map(lambda x: x**2,[1,2,3,4,5) #[1,4,9,16,25]
10.我们可以自己创造高阶函数:(但我感觉用的不是很多吧)
def apply_to_list(fun, some_list):
return fun(some_list)
lst = [1, 2, 3, 4, 5]
print(apply_to_list(sum, lst))
# 15
print(apply_to_list(len, lst))
# 5
print(apply_to_list(lambda x: sum(x) / len(x), lst))
# 3.0
2.类与对象
- 关于
__init__(self, , ):
函数i就是在类被实例化的时候自动执行 - 公有与私有: 注意python里面的私有其实是伪私有,可以用通过特殊的形式弄出来。不论是私有方法还是私有属性
- 继承:继承要注意子如果子类和父类有一样名字的属性和方法会被子类的覆盖掉,然后在子类构造时(用__init__),可以引用父类的部分构造方法
# 类定义
class people:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class student(people):
grade = ''
def __init__(self, n, a, w, g):
# 调用父类的构函
people.__init__(self, n, a, w)
self.grade = g
# 覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
s = student('小马的程序人生', 10, 60, 3)
s.speak()
# 小马的程序人生 说: 我 10 岁了,我在读 3 年级
注意:如果上面的程序去掉:people.__init__(self, n, a, w)
,则输出:说: 我 0 岁了,我在读 3 年级
,因为子类的构造方法把父类的构造方法覆盖了
- 还是关于继承,我们可以使用两种方法来保证子类的
__init__
函数并未覆盖掉父类的构造。第一种是调用未绑定的父类方法Fish.init(self),就是相当于再次把父类的构造在写一遍。第二种就是使用super().__init__()
。这个方法用的比较多,因为简便,下面说说它的一些相关细节 super().__init__()
:当父类中的参数带有默认值时,super().init()调用父类中__init__也可以不传值(或传self),由于传值时self是可以省略的,所以写或不写结果是一样的。self在子类中代表子类本身,把self传到super().init()函数中,代表子类的__init__函数中的内容传给了父类。- 要注意的是当继承了多个父类的时候,如果这些父类都有一个同样的方法,我们应该从左往右进行搜索,即方法未在子类中找到时,从左往右查找父类是否包含方法
# 类定义
class People:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class Student(People):
grade = ''
def __init__(self, n, a, w, g):
# 调用父类的构函
People.__init__(self, n, a, w)
self.grade = g
# 覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
# 另一个类,多重继承之前的准备
class Speaker:
topic = ''
name = ''
def __init__(self, n, t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name, self.topic))
# 多重继承
class Sample01(Speaker, Student):
a = ''
def __init__(self, n, a, w, g, t):
Student.__init__(self, n, a, w, g)
Speaker.__init__(self, n, t)
# 方法名同,默认调用的是在括号中排前地父类的方法
test = Sample01("Tim", 25, 80, 4, "Python")
test.speak()
# 我叫 Tim,我是一个演说家,我演讲的主题是 Python
class Sample02(Student, Speaker):
a = ''
def __init__(self, n, a, w, g, t):
Student.__init__(self, n, a, w, g)
Speaker.__init__(self, n, t)
# 方法名同,默认调用的是在括号中排前地父类的方法
test = Sample02("Tim", 25, 80, 4, "Python")
test.speak()
# Tim 说: 我 25 岁了,我在读 4 年级
- 关于类属性,实例属性
# 创建类对象
class Test(object):
class_attr = 100 # 类属性
def __init__(self):
self.sl_attr = 100 # 实例属性
def func(self):
print('类对象.类属性的值:', Test.class_attr) # 调用类属性
print('self.类属性的值', self.class_attr) # 相当于把类属性 变成实例属性
print('self.实例属性的值', self.sl_attr) # 调用实例属性
a = Test()
a.func()
# 类对象.类属性的值: 100
# self.类属性的值 100
# self.实例属性的值 100
b = Test()
b.func()
# 类对象.类属性的值: 100
# self.类属性的值 100
# self.实例属性的值 100
a.class_attr = 200
a.sl_attr = 200
a.func()
# 类对象.类属性的值: 100
# self.类属性的值 200
# self.实例属性的值 200
b.func()
# 类对象.类属性的值: 100
# self.类属性的值 100
# self.实例属性的值 100
Test.class_attr = 300
a.func()
# 类对象.类属性的值: 300 也就是说类属性只能通过类名来改变,不能通过实例属性来改变
# self.类属性的值 200
# self.实例属性的值 200
b.func()
# 类对象.类属性的值: 300
# self.类属性的值 300
# self.实例属性的值 100
- 属性与方法名相同,属性会覆盖方法。
class A:
def x(self):
print('x_man')
aa = A()
aa.x() # x_man,
aa.x = 1 #在类外给实例对象aa添加属性
print(aa.x) # 1
aa.x()
# TypeError: 'int' object is not callable
- 一些内置函数
issubclass(A,B) #issubclass(class, classinfo)
#这个函数是用来判断B是否是A的父类
#注意如果是issubclass(B,B)也是会返回True
#classinfo可以是类对象的元组,只要class是其中任何一个候选类的子类,则返回True。
isinstance(class,classfo)
#判断一个对象是否是已知的一个类型
#isinstance会认为子类是父类的一种类型,而type()函数则不会这么认为
#如果第一个参数不是对象,将会永远返回False
hasattr(object,name):用于判断对象是否包含对应的属性
class Coordinate:
x = 10
y = -5
z = 0
point1 = Coordinate()
print(hasattr(point1, 'x')) # True
print(hasattr(point1, 'y')) # True
print(hasattr(point1, 'z')) # True
print(hasattr(point1, 'no')) # False
getattr(object,name[,default])用于返回一个对象的属性值
class A(object):
bar = 1
a = A()
print(getattr(a, 'bar')) # 1
print(getattr(a, 'bar2', 3)) # 3
print(getattr(a, 'bar2'))
# AttributeError: 'A' object has no attribute 'bar2'
同上还有delattr()函数和setattr()函数分别用于删除属性和对属性设置值
3、魔法方法
- 迭代器、生成器、以及类里面相关的函数、还有其他的一些知识。但感觉我不太用的到。
三、学习时间:
2021年10月5日 20:11 至21:23 第一天学习(水课上看的,效率不咋高)
2021年10月9日 22:17 至23:39 第二天学习,看到后面不想看了
2021年10月10日20:36 至21:42 第三天学习,魔法方法感觉不太用得到啊
四、学习产出:
- 第一天:感觉补充了点知识
- 第二天:之前关于类的一些知识忘了,现在多看看。
- 第三天:今天把类剩下的看了,然后魔法方法感觉用不太到,就大致的浏览了一下。