python
学习的路径:戳一戳
本篇博客说明
最后的几个知识点,单纯看文档有点吃力,我再去康康视频,后续应该会有他们的详细补发博客,这个只是做个记录。
定义一个简单的类
基本语法:
class 函数名:
函数体
对象名 = 函数名( )
对象名.(需要的数或者方法)
注意:
- 由于下面这个代码,并没有对
name
,age
,height
进行修饰,由于python的值可以到处跑,所以说在下方改变name,也就是把name的值修改了
,所以输出的就不是Bessie_Lee
,而是Bessie
代码显示:
class hh:
name = "Bessie_Lee"
age = 18
height = 161
def major(self):
print("I am a software engineering student")
def time(self):
print("I start to study at half past eight every morning!")
h = hh()
h.major()
h.time()
h.name = "Bessie"
print(h.name)
'''输出:
I am a software engineering student
I start to study at half past eight every morning!
Bessie
'''
使用私有方法(构造方法)__init__
- 下面的类,就可以直接在创建对象名的时候传入对应参数
- 注意:
- 如果传入参数的时候,没有指定哪个传入哪个,就一定要按照类里面的参数顺序传入:
- 对应例子:类里面:
def __init__(self, age, name):
,对应的调用h = hh(18, "Bessie_Lee")
- 对应例子:类里面:
- 如果传入的参数指定哪个传入哪个,就不用管顺序
- 对应例子:类里面:
def __init__(self, age, name):
,对应的调用h = hh(name = "Bessie_Lee", age = 18)
【指定哪个是哪个的参数】
- 对应例子:类里面:
class hh:
def __init__(self, age, name):
self_age = age
self_name = name
def major(self):
print("I am a software engineering student")
def time(self):
print("I start to study at half past eight every morning!")
h = hh(name = "Bessie_Lee", age = 18)
h.major()
h.time()
h.name = "Bessie"
print(h.name)
'''代码输出:
I am a software engineering student
I start to study at half past eight every morning!
Bessie
'''
pass语句+函数
- pass - 啥作用都没有,就是可以给你留一个空格出来,保证代码不会报错
class MyList(list):
pass
lis = MyList([12, 34, 45, 56])
lis.append(89)
lis.sort()
print(lis)
# [12, 34, 45, 56, 89]
调用父类的俩种方法
父类名.__init__(self)
super().__init__()
对应代码:
import random
class Fish:
def __init__(self):
self.x = random.randint(0, 10)
self.y = random.randint(0, 10)
def move(self):
self.x -= 1
print("我的位置", self.x, self.y)
class Shark(Fish): # 鲨鱼
def __init__(self):
# Fish.__init__(self)
super().__init__()
self.hungry = True
def eat(self):
if self.hungry:
print("吃货的梦想就是天天有得吃!")
self.hungry = False
else:
print("太撑了,吃不下了!")
self.hungry = True
a = Shark()
a.eat() #吃货的梦想就是天天有得吃!
同名属性和方法
class A:
x = 10
def x(self):
print("same!")
p = A()
p.x() # same!
p.x = 199
print(p.x) # 199
绑定(我也不太会)
- Python 对象的数据属性通常存储在名为.__ dict__的字典中,我们可以直接访问__dict__,或利用 Python 的内置函数vars()获取.__ dict__。
代码说明:
class CC:
def setXY(self, x, y):
self.x = x
self.y = y
def printXY(self):
print(self.x, self.y)
dd = CC()
print(dd.__dict__) # {}
print(vars(dd)) # {}
print(CC.__dict__) # ①
dd.setXY(4, 5)
print(dd.__dict__) # {'x': 4, 'y': 5}
print(vars(CC)) # ①
print(CC.__dict__) # ①
# 称为:① :{'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000019FB236C4C0>, 'printXY': <function CC.printXY at 0x0000019FB236C550>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}
魔法方法
- 若
__new__
没有正确返回当前类cls
的实例,那__init__
是不会被调用的,即使是父类的实例也不行,将没有__init__
被调用。
利用__new__
实现单例模式
class Earth:
__instance = None # 定义一个类属性做判断
def __new__(cls):
if cls.__instance is None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
return cls.__instance
a = Earth()
print(id(a)) # 2945214668704
b = Earth()
print(id(b)) # 2945214668704
实例化
__new__
方法主要是当你继承一些不可变的 class 时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。
class CapStr(str):
def __new__(cls, string):
string = string.upper()
return str.__new__(cls, string)
a = CapStr("i love lsgogroup")
print(a) # I LOVE LSGOGROUP
加法减法(有点重要)
__add__(self, other)
定义加法的行为:+
__sub__(self, other)
定义减法的行为:-
代码:
class MyClass:
def __init__(self, height, weight):
self.height = height
self.weight = weight
# 两个对象的长相加,宽不变.返回一个新的类
def __add__(self, others):
return MyClass(self.height + others.height, self.weight + others.weight)
# 两个对象的宽相减,长不变.返回一个新的类
def __sub__(self, others):
return MyClass(self.height - others.height, self.weight - others.weight)
# 说一下自己的参数
def intro(self):
print("高为", self.height, " 重为", self.weight)
def main():
a = MyClass(height=10, weight=5)
a.intro()
b = MyClass(height=20, weight=10)
b.intro()
c = b - a
c.intro()
d = a + b
d.intro()
if __name__ == '__main__':
main()
# 高为 10 重为 5
# 高为 20 重为 10
# 高为 10 重为 5
# 高为 30 重为 15
其他方法
__mul__(self, other)
定义乘法的行为:*__truediv__(self, other)
定义真除法的行为:/__floordiv__(self, other)
定义整数除法的行为://__mod__(self, other)
定义取模算法的行为:%__divmod__(self, other)
定义当被divmod()
调用时的行为
divmod(a, b)把
除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
。
反算术运算符(我不懂)
-
反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔法方法多了一个“r”。当文件左操作不支持相应的操作时被调用。
-
注意 self 在后面
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
这个知识点好抽象。。。。。我想看网课,这个文字看的我有点麻
class C:
def __getattribute__(self, item):
print('__getattribute__')
return super().__getattribute__(item)
def __getattr__(self, item):
print('__getattr__')
def __setattr__(self, key, value):
print('__setattr__')
super().__setattr__(key, value)
def __delattr__(self, item):
print('__delattr__')
super().__delattr__(item)
c = C()
c.x
# __getattribute__
# __getattr__
c.x = 1
# __setattr__
del c.x
# __delattr__
描述符
__get__(self, instance, owner)
用于访问属性,它返回属性的值。__set__(self, instance, value)
将在属性分配操作中调用,不返回任何内容。__del__(self, instance)
控制删除操作,不返回任何内容
格式:
class MyDecriptor:
def __get__(self, instance, owner):
print('__get__', self, instance, owner)
def __set__(self, instance, value):
print('__set__', self, instance, value)
def __delete__(self, instance):
print('__delete__', self, instance)
class Test:
x = MyDecriptor()
t = Test()
t.x
# __get__ <__main__.MyDecriptor object at 0x000000CEAAEB6B00> <__main__.Test object at 0x000000CEABDC0898> <class '__main__.Test'>
t.x = 'x-man'
# __set__ <__main__.MyDecriptor object at 0x00000023687C6B00> <__main__.Test object at 0x00000023696B0940> x-man
del t.x
# __delete__ <__main__.MyDecriptor object at 0x000000EC9B160A90> <__main__.Test object at 0x000000EC9B160B38>
编写一个不可改变的自定义列表,要求记录列表中每个元素被访问的次数
class CountList:
def __init__(self, *args):
self.values = [x for x in args]
self.count = {}.fromkeys(range(len(self.values)), 0)
def __len__(self):
return len(self.values)
def __getitem__(self, item):
self.count[item] += 1
return self.values[item]
c1 = CountList(1, 3, 5, 7, 9)
c2 = CountList(2, 4, 6, 8, 10)
print(c1[1]) # 3
print(c2[2]) # 6
print(c1[1] + c2[1]) # 7
print(c1.count)
# {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
print(c2.count)
# {0: 0, 1: 1, 2: 1, 3: 0, 4: 0}
迭代器
- 迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
- 迭代器只能往前不会后退。
- 字符串,列表或元组对象都可用于创建迭代器:
string = 'lsgogroup'
for c in iter(string):
print(c, end = " ")
# l s g o g r o u p
links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}
for each in iter(links):
print(each, end=" ")
print('%s -> %s' % (each, links[each]))
'''
B B -> 百度
A A -> 阿里
T T -> 腾讯
'''
生成器
def libs(n):
a = 0
b = 1
while True:
a, b = b, a + b
if a > n:
return
yield a
for each in libs(100):
print(each, end=' ')
# 1 1 2 3 5 8 13 21 34 55 89