1.对于[[]]*3的理解
Python中的一点反思
![a数到z python python中a[0]_类方法](https://s2.51cto.com/images/blog/202307/04022308_64a3120c6545346925.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![a数到z python python中a[0]_类方法_02](https://s2.51cto.com/images/blog/202307/04022308_64a3120c73e1513025.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
由此可以看出,a[0],a[1],a[2]指向的是同一个元素,[[]]*3表示在a中开辟三份地址,且地址相同。a[0]找到的是a中第一个列表。a[0][0]找到的是其中的第一个列表的第一个元素。
![a数到z python python中a[0]_赋值_03](https://s2.51cto.com/images/blog/202307/04022308_64a3120c8302641389.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![a数到z python python中a[0]_a数到z python_04](https://s2.51cto.com/images/blog/202307/04022308_64a3120c95559563.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
重新对a[0]赋值,故a[0]地址改变。其余的地址不做改变,赋值也仅对a[0]赋值,对其他元素不做影响。
![a数到z python python中a[0]_a数到z python_05](https://s2.51cto.com/images/blog/202307/04022308_64a3120ca488e63113.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
![a数到z python python中a[0]_赋值_06](https://s2.51cto.com/images/blog/202307/04022308_64a3120cb34c297563.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
对a[0][0]赋值,即改变a[0],a[1],a[2]指向的地址里的内容。
这就像[[]],在a列表中开辟了三个平行地址空间。当对其中一个a[0]做修改的时候,其内部的值当然被修改但随之地址也将改变。但是对其中一个列表的内部元素a[0][0]做修改的时候,就不会对地址其他平行地址进行修改。
注: .append\+=\-=等都不会重新赋地址,=会重新赋地址 故而,下面两条语句都会出现问题:
我用到了[[]]*len(spts),所以只要其中某一个[]之后有.append或+=或其它不重新指向地址的行为,另外两个元素也会跟着改变。
2.python装饰器
python装饰器
主要分为abstractmethod, property, staticmethod, classmethod
abstractmethod:指的是抽象方法,含有abstractmethod的类是无法实例化的, 继承含有abstractmethod方法的类的是可以实例化的,但需要全部复写被abstract修饰的方法
property:为伪装属性,方法返回的值与属性,不能含有参数,不能被类调用
classmethod:为类属性,可以被实例和类进行调用,被引用的第一个参数通常为cls,函数内部可以调用类但无法调用实例
staticmethod:静态属性,可以通过实例对象和类对象进行调用,可以没有参数,可以通过实例.属性进行调用,不能调用实例对象
@abstractmethod
用于程序接口的控制,正如上面的特性,含有@abstractmethod修饰的父类不能实例化,但是继承的子类必须实现@abstractmethod装饰的方法
# -*- coding:utf-8 -*-
from abc import ABC, abstractmethod
class **A**(**ABC**):
@abstractmethod
def **test**(self):
pass
class **B**(**A**):
def **test_1**(self):
print("未覆盖父类abstractmethod")
class **C**(**A**):
def **test**(self):
print("覆盖父类abstractmethod")
if __name__ == '__main__':
a = A()
b = B()
c = C()
前两个分别报错如下:
a = A()
TypeError: Can't instantiate abstract class A with abstract methods test
b = B()
TypeError: Can't instantiate abstract class **B** **with** **abstract** **methods** **test**
第三个实例化是正确的 @ property
将一个方法伪装成属性,被修饰的特性方法,内部可以实现处理逻辑,但对外提供统一的调用方式,实现一个实例属性的get,set,delete三种方法的内部逻辑,具体含义看示例code。
1 # -*- coding:utf-8 -*-
2
3 # -*- coding:utf-8 -*-
4
5 class **Data**:
6 def **__init__**(self):
7 self.number = 123
8
9 @property
10 def **operation**(self):
11 return self.number
12
13 @operation.setter
14 def **operation**(self, number):
15 self.number = number
16
17 @operation.deleter
18 def **operation**(self):
19 del self.number
@ classmethod,staticmethod
类方法classmethod和静态方法staticmethod是为类操作准备,是将类的实例化和其方法解耦,可以在不实例化的前提下调用某些类方法。两者的区别可以这么理解:类方法是将类本身作为操作对象,而静态方法是独立于类的一个单独函数,只是寄存在一个类名下。类方法可以用过类属性的一些初始化操作。
# -*- coding:utf-8 -*-
class **Test**:
num = "aaaa"
def **__init__**(self):
self.number = 123
@classmethod
def **a**(cls, n):
cls.num = n
print(cls.num)
@classmethod
def **b**(cls, n):
cls.a(n)
@classmethod
def **c**(cls, n):
cls.number = n
@staticmethod
def **d**(n):
Test.b(n)
















