python数组类变量内的数组数据被同时修改了,该怎么解决

2020-05-14 14:29发布

代码如下:classStudent: name='' score=[] def__init__(self): pass defmain(): all=[] all.append(St...

代码如下:

class Student:
    name = ''
    score = []
    def __init__(self):
        pass

def main():
    all = []
    all.append(Student())
    all.append(Student())
    all[0].name = 'YYY'
    all[1].name = 'XXX'
    all[0].score.append(75)
    all[1].score.append(85)
    print(all[0].score, all[1].score)

if __name__ == "__main__":
    main()


2条回答
春风
2楼 · 2020-05-14 17:28

因为类变量是可变数据类型的话,变量的内存地址是相同的,所以当添加数据时,两个数据都会发生修改。

大泽九章
3楼 · 2020-12-02 14:18





使用python向C语言的链接库传递数组、结构体、指针类型的数据

由于最近的项目频繁使用python调用同事的C语言代码,在调用过程中踩了很多坑,一点一点写出来供大家参考,我们仍然是使用ctypes来调用C语言的代码库。至于如何调用基础数据类型的数据,请大家参考我的另外一篇文章:python使用ctypes调用C/C++

  1. 使用python给C语言函数传递数组类型的参数

  2. 想必很多时候,C语言会使用数组作为参数,在之前我们使用过ctypes的一些数据类型作为C语言参数类型,包括byte、short、int、double之类的,但是在使用数组类型的时候,我们也是有着类似的做法,下面我们看实例:

  3. 1.1C语言的代码块

  4. 一个简单的数组输入,以及一个简单将数组作为参数的函数

  5. intinput[2]=[0,1]

voidprintIntArray(int[]input){

for(inti=0;i<2>

print(input[i]);

}

}


1.2python代码块

下面我们将演示如何调用上面的代码

fromctypesimport*


#假设上面的代码被编译成了一个XXXXlib.so的文件

dll=CDLL('XXXXlib.so')


#声明一个数组类型

INPUT=c_int*2

#实例化一个长度为2的整型数组

input=INPUT()

#为数组赋值(input这个数组是不支持迭代的)

input[0]=1

input[1]=2


#引用C语言的函数

print_int_array=dll.printIntArray

#调用C语言的函数

print_int_array(input)


1.3总结

使用数组的方法基本就是这样的,声明什么类型的数组只需要根据之前python官方文档里ctypes使用说明对照着声明数组就可以了。

2.使用python给C语言函数传递结构体类型的参数

当然,为了满足一些个性化的需求和为了使程序更容易让人理解,更多的时候开发人员也会使用结构体类型的变量为函数赋值。现在我们使用ctypes来实例化一个C语言的结构体,请看实例:由于第一部分我们已经介绍了如何简单的调用C语言的函数,我们下面只写结构体相关的python代码

fromctypesimport*


#声明一个类,继承自ctypes.Structure

classPythonStructure(Structure):

_fields_:[('param1',c_int),('param2',c_int),('param3',c_int*2)]



#实例化变量

python_structure=PythonStructure()

#赋值

python_structure.param1=1

python_structure.param2=3

PARAM=c_int*2

param3=PARAM()

param3[0]=3

param3[1]=4

python_structure.param3=param3


从代码中我们可以看到,我们声明了一个class,使其继承自ctypes.Structure,然后在类的内部声明了变量,fields这样一个变量域,里面用元组存贮这结构体的每个结构体内部变量的变量名和数据类型。然后在实际的使用过程中,首先要实例化一个PythonStructure类型的变量,然后为其各个内部变量赋值。

3.使用python给C语言函数传递指针类型的参数

指针作为C语言相比于其他原因最大的优势,在C语言程序中会大量的使用指针,因此将指针类型的数据作为参数传递其实是十分的普遍的,下面我们直接上实例:

3.1C语言函数声明

voidtest(pystruct*ps)


假设这里的pystruct与我们在第二部分声明的结构体相对应(我这渣渣C语言功底实在是怕写出什么错误的代码误导大家)

3.2python代码

使用指针类型的数据只需要在调用btref()就可以了

fromctypesimport*


#声明一个类,继承自ctypes.Structure

classPythonStructure(Structure):

_fields_:[('param1',c_int),('param2',c_int),('param3',c_int*2)]



#实例化变量

python_structure=PythonStructure()

#赋值

python_structure.param1=1

python_structure.param2=3

PARAM=c_int*2

param3=PARAM()

param3[0]=3

param3[1]=4

python_structure.param3=param3


#开始调用

dll=CDLL('XXXXlib.so')

test=dll.test

#传递参数

test(byref(python_structure))


4.写在最后

以上就是我们今天踩过的坑,其实发现网上对于ctypes的相关博客不是很多,因此想写出来跟大家分享一下,希望大家少踩坑,快速的完成任务,远离加班,周末愉快!


相关问题推荐

  • 回答 3

    换行。比如,print hello\nworld效果就是helloworld\n就是一个换行符。\是转义的意思,&#39;\n&#39;是换行,&#39;\t&#39;是tab,&#39;\\&#39;是,\ 是在编写程序中句子太长百,人为换行后加上\但print出来是一整行。...

  • 回答 42

    十种常见排序算法一般分为以下几种:(1)非线性时间比较类排序:a. 交换类排序(快速排序、冒泡排序)b. 插入类排序(简单插入排序、希尔排序)c. 选择类排序(简单选择排序、堆排序)d. 归并排序(二路归并排序、多路归并排序)(2)线性时间非比较类排序:...

  • 回答 70
    已采纳

    前景很好,中国正在产业升级,工业机器人和人工智能方面都会是强烈的热点,而且正好是在3~5年以后的时间。难度,肯定高,要求你有创新的思维能力,高数中的微积分、数列等等必须得非常好,软件编程(基础的应用最广泛的语言:C/C++)必须得很好,微电子(数字电...

  • 回答 28

    迭代器与生成器的区别:(1)生成器:生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅记住了它的数据状态,生成器还记住了程序...

  • 回答 9

    python中title( )属于python中字符串函数,返回’标题化‘的字符串,就是单词的开头为大写,其余为小写

  • 回答 6

    第一种解释:代码中的cnt是count的简称,一种电脑计算机内部的数学函数的名字,在Excel办公软件中计算参数列表中的数字项的个数;在数据库( sq| server或者access )中可以用来统计符合条件的数据条数。函数COUNT在计数时,将把数值型的数字计算进去;但是...

  • 回答 1

    head是方法,所以需要取小括号,即dataset.head()显示的则是前5行。data[:, :-1]和data[:, -1]。另外,如果想通过位置取数据,请使用iloc,即dataset.iloc[:, :-1]和dataset.iloc[:, -1],前者表示的是取所有行,但不包括最后一列的数据,结果是个DataFrame。...

  • Python入门简单吗2021-09-23 13:21
    回答 45

    挺简单的,其实课程内容没有我们想象的那么难、像我之前同学,完全零基础,培训了半年,直接出来就工作了,人家还在北京大公司上班,一个月15k,实力老厉害了

  • 回答 4

    Python针对众多的类型,提供了众多的内建函数来处理(内建是相对于导入import来说的,后面学习到包package时,将会介绍),这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Pyt...

  • 回答 8

     相当于 ... 这里不是注释

  • 回答 4

    还有FIXME

  • 回答 3

    python的两个库:xlrd和xlutils。 xlrd打开excel,但是打开的excel并不能直接写入数据,需要用xlutils主要是复制一份出来,实现后续的写入功能。

  • 回答 8

    单行注释:Python中的单行注释一般是以#开头的,#右边的文字都会被当做解释说明的内容,不会被当做执行的程序。为了保证代码的可读性,一般会在#后面加一两个空格然后在编写解释内容。示例:#  单行注释print(hello world)注释可以放在代码上面也可以放在代...

  • 回答 2

    主要是按行读取,然后就是写出判断逻辑来勘测行是否为注视行,空行,编码行其他的:import linecachefile=open(&#39;3_2.txt&#39;,&#39;r&#39;)linecount=len(file.readlines())linecache.getline(&#39;3_2.txt&#39;,linecount)这样做的过程中发现一个问题,...

  • 回答 4

    或许是里面有没被注释的代码

  • 回答 26

    自学的话要看个人情况,可以先在B站找一下视频看一下

没有解决我的问题,去提问