导航:首页 > 编程语言 > python能模拟出地层吗

python能模拟出地层吗

发布时间:2023-04-18 17:57:17

1. ue5python原理

Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器一条一条执行字节码指令,从而完成程序的执行。

1.1python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器会从编译得到的PyCodeObject对象中一条一条执行字节码指令,
并在当前的上下文环境中执行这条字节码指令,从而完成程序的执行。Python解释器实际上是在模拟操作中执行文件的过程。PyCodeObject对象
中包含了字节码指令以及程序的所有静态信息,但没有包含程序运行时的动态信息——执行环境(PyFrameObject)

2. 字节码
字节码在python解释器程序里对应的是PyCodeObject对象
.pyc文件是字节码在磁盘上的表现形式

2.1从整体上看:OS中执行程序离不开两个概念:进程和线程。python中模拟了这两个概念,模拟进程和线程的分别是PyInterpreterState和
PyTreadState。即:每个PyThreadState都对应着一个帧栈,python解释器在多个线程上切换。当python解释器开始执行时,它会先进行一
些初始化操作,最后进入PyEval_EvalFramEx函数,它的作用是不断读取编译好的字节码,并一条一条执行,类似CPU执行指令的过程。函数内部
主要是一个switch结构,根据字节码的不同执行不同的代码。

3. .pyc文件
PyCodeObject对象的创建时机是模块加载的时候,及import
Python test.py会对test.py进行编译成字节码并解释执行,但是不会生成test.pyc
如果test.py加载了其他模块,如import urlib2, Python会对urlib2.py进行编译成字节码,生成urlib2.pyc,然后对字节码进行解释
如果想生成test.pyc,我们可以使用Python内置模块py_compile来编译。
加载模块时,如果同时存在.py和pyc,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则重新编译.py并更新.pyc。

4. PyCodeObject
Python代码的编译结果就是PyCodeObject对象

typedef struct {
PyObject_HEAD
int co_argcount; /* 位置参数个数 */
int co_nlocals; /* 局部变量个数 */
int co_stacksize; /* 栈大小 */
int co_flags;
PyObject *co_code; /* 字节码指令序列 */
PyObject *co_consts; /* 所有常量集合 */
PyObject *co_names; /* 所有符号名称集合 */
PyObject *co_varnames; /* 局部变量名称集合 */
PyObject *co_freevars; /* 闭包用的的变量名集合 */
PyObject *co_cellvars; /* 内部嵌套函数引用的变量名集合 */
/* The rest doesn’t count for hash/cmp */
PyObject *co_filename; /* 代码所在文件名 */
PyObject *co_name; /* 模块名|函数名|类名 */
int co_firstlineno; /* 代码块在文件中的起始行号 */
PyObject *co_lnotab; /* 字节码指令和行号的对应关系 */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
} PyCodeObject;

5. .pyc文件格式
加载模块时,模块对应的PyCodeObject对象被写入.pyc文件

6.分析字节码

6.1解析PyCodeObject
Python提供了内置函数compile可以编译python代码和查看PyCodeObject对象

6.2指令序列co_code的格式

opcode oparg opcode opcode oparg …
1 byte 2 bytes 1 byte 1 byte 2 bytes
Python内置的dis模块可以解析co_code

7. 执行字节码
Python解释器的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图

Python解释器的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。
PyFrameObject对象创建程序运行时的动态信息,即执行环境

7.1 PyFrameObject

typedef struct _frame{
PyObject_VAR_HEAD //"运行时栈"的大小是不确定的
struct _frame *f_back; //执行环境链上的前一个frame,很多个PyFrameObject连接起来形成执行环境链表
PyCodeObject *f_code; //PyCodeObject 对象,这个frame就是这个PyCodeObject对象的上下文环境
PyObject *f_builtins; //builtin名字空间
PyObject *f_globals; //global名字空间
PyObject *f_locals; //local名字空间
PyObject **f_valuestack; //"运行时栈"的栈底位置
PyObject **f_stacktop; //"运行时栈"的栈顶位置
//...
int f_lasti; //上一条字节码指令在f_code中的偏移位置
int f_lineno; //当前字节码对应的源代码行
//...

//动态内存,维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间
PyObject *f_localsplus[1];
} PyFrameObject;

每一个 PyFrameObject对象都维护了一个 PyCodeObject对象,这表明每一个 PyFrameObject中的动态内存空间对象都和源代码中的一段Code相对应。

2. 一篇文章带你深度解析Python线程和进程

使用Python中的线程模块,能够同时运行程序的不同部分,并简化设计。如果你已经入门Python,并且想用线程来提升程序运行速度的话,希望这篇教程会对你有所帮助。

线程与进程

什么是进程

进程是系统进行资源分配和调度的一个独立单位 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

什么是线程

CPU调度和分派的基本单位 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

进程与线程的关系图

线程与进程的区别:

进程

现实生活中,有很多的场景中的事情是同时进行的,比如开车的时候 手和脚共同来驾驶 汽车 ,比如唱歌跳舞也是同时进行的,再比如边吃饭边打电话;试想如果我们吃饭的时候有一个领导来电,我们肯定是立刻就接听了。但是如果你吃完饭再接听或者回电话,很可能会被开除。

注意:

多任务的概念

什么叫 多任务 呢?简单地说,就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行。还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已。

现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行多任务。由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多任务的呢?

答案就是操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒,这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。

真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。 其实就是CPU执行速度太快啦!以至于我们感受不到在轮流调度。

并行与并发

并行(Parallelism)

并行:指两个或两个以上事件(或线程)在同一时刻发生,是真正意义上的不同事件或线程在同一时刻,在不同CPU资源呢上(多核),同时执行。

特点

并发(Concurrency)

指一个物理CPU(也可以多个物理CPU) 在若干道程序(或线程)之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。

特点

multiprocess.Process模块

process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。

语法:Process([group [, target [, name [, args [, kwargs]]]]])

由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)。

注意:1. 必须使用关键字方式来指定参数;2. args指定的为传给target函数的位置参数,是一个元祖形式,必须有逗号。

参数介绍:

group:参数未使用,默认值为None。

target:表示调用对象,即子进程要执行的任务。

args:表示调用的位置参数元祖。

kwargs:表示调用对象的字典。如kwargs = {'name':Jack, 'age':18}。

name:子进程名称。

代码:

除了上面这些开启进程的方法之外,还有一种以继承Process的方式开启进程的方式:

通过上面的研究,我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发处理,他们之间的运行没有顺序,一旦开启也不受我们控制。尽管并发编程让我们能更加充分的利用IO资源,但是也给我们带来了新的问题。

当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题,我们可以考虑加锁,我们以模拟抢票为例,来看看数据安全的重要性。

加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改。加锁牺牲了速度,但是却保证了数据的安全。

因此我们最好找寻一种解决方案能够兼顾:1、效率高(多个进程共享一块内存的数据)2、帮我们处理好锁问题。

mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。队列和管道都是将数据存放于内存中 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来, 我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性( 后续扩展该内容 )。

线程

Python的threading模块

Python 供了几个用于多线程编程的模块,包括 thread, threading 和 Queue 等。thread 和 threading 模块允许程序员创建和管理线程。thread 模块 供了基本的线程和锁的支持,而 threading 供了更高级别,功能更强的线程管理的功能。Queue 模块允许用户创建一个可以用于多个线程之间 共享数据的队列数据结构。

python创建和执行线程

创建线程代码

1. 创建方法一:

2. 创建方法二:

进程和线程都是实现多任务的一种方式,例如:在同一台计算机上能同时运行多个QQ(进程),一个QQ可以打开多个聊天窗口(线程)。资源共享:进程不能共享资源,而线程共享所在进程的地址空间和其他资源,同时,线程有自己的栈和栈指针。所以在一个进程内的所有线程共享全局变量,但多线程对全局变量的更改会导致变量值得混乱。

代码演示:

得到的结果是:

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行(其中的JPython就没有GIL)。

那么CPython实现中的GIL又是什么呢?GIL全称Global Interpreter Lock为了避免误导,我们还是来看一下官方给出的解释:

主要意思为:

因此,解释器实际上被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。在多线程环境中,Python 虚拟机按以下方式执行:

由于GIL的存在,Python的多线程不能称之为严格的多线程。因为 多线程下每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程在运行。

由于GIL的存在,即使是多线程,事实上同一时刻只能保证一个线程在运行, 既然这样多线程的运行效率不就和单线程一样了吗,那为什么还要使用多线程呢?

由于以前的电脑基本都是单核CPU,多线程和单线程几乎看不出差别,可是由于计算机的迅速发展,现在的电脑几乎都是多核CPU了,最少也是两个核心数的,这时差别就出来了:通过之前的案例我们已经知道,即使在多核CPU中,多线程同一时刻也只有一个线程在运行,这样不仅不能利用多核CPU的优势,反而由于每个线程在多个CPU上是交替执行的,导致在不同CPU上切换时造成资源的浪费,反而会更慢。即原因是一个进程只存在一把gil锁,当在执行多个线程时,内部会争抢gil锁,这会造成当某一个线程没有抢到锁的时候会让cpu等待,进而不能合理利用多核cpu资源。

但是在使用多线程抓取网页内容时,遇到IO阻塞时,正在执行的线程会暂时释放GIL锁,这时其它线程会利用这个空隙时间,执行自己的代码,因此多线程抓取比单线程抓取性能要好,所以我们还是要使用多线程的。

GIL对多线程Python程序的影响

程序的性能受到计算密集型(CPU)的程序限制和I/O密集型的程序限制影响,那什么是计算密集型和I/O密集型程序呢?

计算密集型:要进行大量的数值计算,例如进行上亿的数字计算、计算圆周率、对视频进行高清解码等等。这种计算密集型任务虽然也可以用多任务完成,但是花费的主要时间在任务切换的时间,此时CPU执行任务的效率比较低。

IO密集型:涉及到网络请求(time.sleep())、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。

当然为了避免GIL对我们程序产生影响,我们也可以使用,线程锁。

Lock&RLock

常用的资源共享锁机制:有Lock、RLock、Semphore、Condition等,简单给大家分享下Lock和RLock。

Lock

特点就是执行速度慢,但是保证了数据的安全性

RLock

使用锁代码操作不当就会产生死锁的情况。

什么是死锁

死锁:当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。即死锁是指多个进程因竞争资源而造成的一种僵局,若无外力作用,这些进程都将无法向前推进。

所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。

死锁代码

python线程间通信

如果各个线程之间各干各的,确实不需要通信,这样的代码也十分的简单。但这一般是不可能的,至少线程要和主线程进行通信,不然计算结果等内容无法取回。而实际情况中要复杂的多,多个线程间需要交换数据,才能得到正确的执行结果。

python中Queue是消息队列,提供线程间通信机制,python3中重名为为queue,queue模块块下提供了几个阻塞队列,这些队列主要用于实现线程通信。

在 queue 模块下主要提供了三个类,分别代表三种队列,它们的主要区别就在于进队列、出队列的不同。

简单代码演示

此时代码会阻塞,因为queue中内容已满,此时可以在第四个queue.put('苹果')后面添加timeout,则成为 queue.put('苹果',timeout=1)如果等待1秒钟仍然是满的就会抛出异常,可以捕获异常。

同理如果队列是空的,无法获取到内容默认也会阻塞,如果不阻塞可以使用queue.get_nowait()。

在掌握了 Queue 阻塞队列的特性之后,在下面程序中就可以利用 Queue 来实现线程通信了。

下面演示一个生产者和一个消费者,当然都可以多个

使用queue模块,可在线程间进行通信,并保证了线程安全。

协程

协程,又称微线程,纤程。英文名Coroutine。

协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。为啥说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。

通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定。

在实现多任务时,线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。

greenlet与gevent

为了更好使用协程来完成多任务,除了使用原生的yield完成模拟协程的工作,其实python还有的greenlet模块和gevent模块,使实现协程变的更加简单高效。

greenlet虽说实现了协程,但需要我们手工切换,太麻烦了,gevent是比greenlet更强大的并且能够自动切换任务的模块。

其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。

模拟耗时操作:

如果有耗时操作也可以换成,gevent中自己实现的模块,这时候就需要打补丁了。

使用协程完成一个简单的二手房信息的爬虫代码吧!

以下文章来源于Python专栏 ,作者宋宋

文章链接:https://mp.weixin.qq.com/s/2r3_ipU3HjdA5VnqSHjUnQ

3. python能做什么

1、做日常任务,比如下载视频、MP3、自动化操作excel、自动发邮件。

2、做网站开发、web应用开发,很多着名的网站像知乎、YouTube就是Python写的。

许多大型网站就是用Python开发的,例如YouTube、Instagram,还有国内的豆瓣。很多大公司,包括Google、Yahoo等,甚至NASA(美国航空航天局)都大量地使用Python。

3、做网络游戏的后台,很多在线游戏的后台都是Python开发的。

4、系统网络运维

Linux运维是必须而且一定要掌握Python语言,它可以满足Linux运维工程师的工作需求提升效率,总而提升自己的能力,运维工程师需要自己独态穗立开发一个完整的自动化系统时,这个时候才是真正价值的体现,才能证明自身的能力,让老板重视。



5、3D游戏开发

Python也可以用来做游戏开发,因为它有很好的3D渲染库和游戏开发框架,目前来说就有很多使用Python开发的游戏,如迪斯尼卡通城、黑暗之刃。

6、科学与数字计算

我们都知道现在来临了大数据的时代,数据可以说明一切问题的原因,现在很多做数据分析的不是原来那么简单,Python语言成为了做数据分析师的第一首选,它同时可以给工作带来很大的效率。

7、人工智能

人工智能是一门极富挑战性的科学,帆散卜从事这项工作的人必须懂得计算机知识,心理学和哲学。人工智能是包括十分广泛的科学,它由不同的领域掘胡组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。Python语言对于人工智能来说是最好的语言。目前好多人都开始学习人工智能+Python学科。

8、网络爬虫

爬虫是属于运营的比较多的一个场景吧,比如谷歌的爬虫早期就是用跑Python写的. 其中有一个库叫 Requests ,这个库是一个模拟HTTP请求的一个库,非常的出名! 学过Python的人没有不知道这个库吧,爬取后的数据分析与计算是Python最为擅长的领域,非常容易整合。不过目前Python比较流行的网络爬虫框架是功能非常强大的scrapy。

9、数据分析

一般我们用爬虫爬到了大量的数据之后,我们需要处理数据用来分析,不然爬虫白爬了,我们最终的目的就是分析数据,在这方面 关于数据分析的库也是非常的丰富的,各种图形分析图等 都可以做出来。也是非常的方便,其中诸如Seaborn这样的可视化库,能够仅仅使用一两行就对数据进行绘图,而利用Pandas和numpy、scipy则可以简单地对大量数据进行筛选、回归等计算。

而后续复杂计算中,对接机器学习相关算法,或者提供Web访问接口,或是实现远程调用接口,都非常简单。

4. Python数据结构-队列与广度优先搜索(Queue)

队列(Queue) :简称为队,一种线性表数据结构,是一种只允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表。
我们把队列中允许插入的一端称为 “队尾(rear)” ;把允许删除的另一端称为 “队头(front)” 。当表中没有任何数据元素时,称之为 “空队”

广度优先搜索算法(Breadth First Search) :简称为 BFS,又译作宽度优先搜索 / 横向优先搜索。是一种用于遍历或搜索树或图的算法。该算法从根节点开始,沿着树的宽度遍历树或图的节点。如果所有节点均被访问,则算法中止。

广度优先遍历 类似于树的层次遍历过程 。呈现出一层一层向外扩张的特点。先看到的节点先访问,后看到的节点后访问。遍历到的节点顺序符合“先进先出”的特点,所以广度优先搜索可以通过“队列”来实现。

力扣933

游戏时,队首始终是持有薯仔的人
模拟游戏开始,队首的人出队,之后再到队尾(类似于循环队列)
传递了num次之后,将队首的人移除
如此反复,直到队列中剩余一人

多人共用一台打印机,采取“先到先服务”的队列策略来执行打印任务
需要解决的问题:1 打印系统的容量是多少?2 在能够接受的等待时间内,系统可容纳多少用户以多高的频率提交打印任务?

输入:abba
输出:False
思路:1 先将需要判定的词从队尾加入 deque; 2从两端同时移除字符并判断是否相同,直到deque中剩余0个(偶数)或1个字符(奇数)

内容参考: https://algo.itcharge.cn/04.%E9%98%9F%E5%88%97/01.%E9%98%9F%E5%88%97%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/01.%E9%98%9F%E5%88%97%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/

5. python能做什么游戏

Python是一门高级且有趣的编程语言,除了网络爬虫、人工智能、数据分析之外,Python还可以进行游戏开发,为大家介绍五个支持Python的2D、3D游戏开发库。
1、Cocos2d:是一系列开源软件框架,用于构建跨平台2D游戏和应用程序,由cocos2d-x、cocos2d-js、cocos2d-xna和cocos2d多种框架组成,像大鱼赌场、城堡冲突等小游戏,就是用此框架开发出来的。
2、Panda3D:是由迪士尼开发的3D游戏引擎,一个用于Python和C++程序的3D渲染和游戏开发框架,并由卡内基梅陇娱乐技术中心负责维护,使用C++编写的,针对Python进行了完全的封装。
3、Pygame:它是一组Python模块,用来编写游戏,可支持Python3.7,游戏例子有:纸牌游戏、超级马里奥、击球等多种游戏。
4、Pyogre:ogre 3D渲染引擎的Python绑定,可以用来开发游戏和仿真程序等任何3D应用,它的API更加稳定,也非常快速灵活。
5、RenPy:一个视觉小说引擎,被世界各地的成千万的创造者所使用,它可以帮助你使用文字、图像和声音来讲述电脑和移动设备上的故事。RenPy是开放源码的,可免费的商业用途,易于学习的脚本语言任何人都能有效地编写大型视觉小说,它的Python脚本足以用来模拟游戏。

6. 使用Matplotlib模拟Python中的三维太阳系

编程的一个用途是通过模拟来帮助我们理解真实世界。这一技术被应用于科学、金融和许多其他定量领域。只要控制现实世界属性的“规则”是已知的,你就可以编写一个计算机程序来 探索 你遵循这些规则所得到的结果。在本文中,您将 用Python模拟三维太阳系 使用流行的可视化库Matplotlib

在这篇文章,你将能够用Python创建你自己的3D太阳系,你可以用你想要的多少太阳和行星。下面是一个简单的太阳系的一个例子,它有一个太阳和两个行星:

你还可以打开动画地板上的二维投影,更好地展示太阳系的三维本质。下面是同样的太阳系模拟,包括2D投影:

下面是这篇文章的概要,以便您知道接下来会发生什么:

在本文中,您将使用面向对象的编程和Matplotlib。如果您希望阅读更多关于任何一个主题的内容,您可以阅读:

让我们从使用Matplotlib在Python中模拟一个3D太阳系开始。

太阳系中的太阳、行星和其他天体都是运动中的天体,它们相互吸引。引力在任何两个物体之间施加。

如果这两个对象有大量M_1和M_2是距离r然后,你可以用以下公式计算它们之间的引力:

常数G是一个引力常数。您将看到如何在模拟的版本中忽略这个常量,在本文中,您将使用任意单位的质量和距离,而不是kg和m。

一旦你知道了两个物体之间的引力,你就可以计算出加速度。a每个物体都是由于这种引力而经历的,使用以下公式:

使用这个加速度,你可以调整运动物体的速度。当速度发生变化时,速度和方向都会发生变化。

当用Python模拟一个三维太阳系时,你需要用三维空间来表示太阳系。因此,这个3D空间中的每个点都可以用三个数字来表示, x -, y -和 z -坐标。例如,如果你想把太阳放在太阳系的中心,你可以将太阳的位置表示为 (0, 0, 0) .

您还需要在3D空间中表示向量。矢量具有大小和方向。你需要像速度、加速度和力这样的量的矢量,因为这些量都有一个方向和一个震级。

在本文中,我将不详细讨论向量代数。相反,我将陈述您需要的任何结果。你可以读到更多关于向量与向量代数如果你愿意的话。

为了在代码中更容易地处理向量,您可以创建一个类来处理它们。编写这个类将作为对类和面向对象编程的快速刷新。你可以读到用Python进行面向对象的编程如果你觉得你需要一个更彻底的解释。虽然您也可以创建一个类来处理3D空间中的点,但这并不是必要的,在本文中我也不会创建一个类。

如果您熟悉向量和面向对象编程,可以跳过本节,只需在定义 Vector 班级。

创建一个名为 vectors.py 中,您将定义 Vector 班级。您将使用此脚本定义类并对其进行测试。然后,可以删除最后的测试代码,只需在这个脚本中保留类定义:

这个 __init__() 方法的 Vector 类有三个参数,表示每个轴上的值。每个参数的默认值为 0 表示该轴的原点。虽然我们不喜欢在Python中使用单个字母名称, x , y ,和 z 是恰当的,因为它们代表了数学中常用的笛卡尔坐标系的术语。

您还定义了两个Dunder方法来将对象表示为一个字符串:

在代码段的末尾,您可以更多地了解这两种类型的字符串表示之间的差异。Python编码书第9章 .

测试代码块的输出如下:

在Python项目中的这个3D太阳系中,如果 Vector 类是可索引的,以便您可以使用 [] 带有索引以提取其中一个值的符号。使用当前形式的类,如果添加 print(test[0]) 在您的脚本中,您将得到一个 TypeError 说 Vector 对象不可订阅。您可以通过向类定义中添加另一个Dud方法来修复这个问题:

通过定义 __getitem__() ,你做了 Vector 可索引的类。向量中的第一项是 x 的价值。 y 的价值。 z 。任何其他索引都会引发错误。测试代码块的输出如下:

test[0] 返回向量中的第一个项, x .

可以定义类的对象的加法和减法。 __add__() 和 __sub__() DunderMethod.这些方法将使您能够使用 + 和 - 执行这些操作的符号。如果没有这些Dud方法,则使用 + 和 - 提出 TypeError .

若要添加或减去两个向量,可以分别添加或减去向量的每个元素:

双管齐下 __add__() 和 __sub__() 返回另一个 Vector 对象,每个元素等于两个原始向量中相应元素的加减。输出如下:

对于乘法和除法,您也可以这样做,尽管在处理向量时,这些操作需要更多的注意。

在处理向量时,不能仅仅引用“乘法”,因为有不同类型的“乘法”。在这个项目中,你只需要标量乘法。标量乘法是指向量与标量相乘(标量有一个数量级,但没有方向)。但是,在本小节中,您还将定义点积两个向量。你想用 * 运算符,既适用于标量乘法,也适用于点积。因此,可以定义 __mul__() DunderMethod:

使用 * 运算符将取决于第二个操作数,即 * 符号,是标量或向量。如果由参数表示的第二个操作数 other ,是类型的 Vector ,计算了点积。但是,如果 other 是类型的 int 或 float ,返回的结果是一个新的 Vector ,按比例调整。

以上代码的输出如下:

如果您想要标量乘法,则需要标量乘法。 后 这个 * 象征。如果您试图运行该语句 3*Vector(3, 5, 9) 相反, TypeError 将被提高,因为 Vector 类不是用于使用的有效操作数。 * 带有类型的对象 int .

两个向量是分不开的。但是,可以将向量除以标量。您可以使用 / 运算符 Vector 如果定义 __truep__() DunderMethod:

产出如下:

如果你有一个向量(x,y,z),您可以找到它的震级使用表达式(x^2+y^2+z^2)。你也可以规范化向量。归一化给出一个方向相同但大小为 1 。您可以通过将向量的每个元素除以矢量的大小来计算归一化向量。

可以定义两个新方法来完成 Vector 班级:

测试代码提供了以下输出:

第三个输出给出了归一化向量的大小,表明它的大小是 1 .

根据使用的IDE或其他工具,在分割时可能会收到警告 self.x , self.y ,和 self.z ,如在 __truep__() 和 normalize() 。您不需要担心这个问题,但是如果您想要修复它,可以通过更改 __init__() 签署下列任何一项:

这两个选项都让IDE知道参数应该是浮动的。在第二个选项中,您使用类型暗示来实现。

您现在可以删除此脚本末尾的测试代码,以便您在 vectors.py 是类的定义。

现在,你可以开始研究Python中的3D太阳系了。您将创建两个主要类:

你将使用Matplotlib来创建和可视化太阳系。您可以在终端中使用以下内容来安装Matplotlib:

这个 Axes3D Matplotlib中的物体将“托管”太阳系。如果您使用过Matplotlib,并且主要使用了2D绘图,那么您将使用(有意或不知情的) Axes 对象。 Axes3D 的3D等效 Axes ,顾名思义!

现在是开始编写和测试这些类的时候了。您可以创建两个新文件:

接下来,您将开始处理 SolarSystem 班级。

您将在整个项目中使用任意单元。这意味着,与其用米作为距离,而用公斤作为质量,你将使用没有单位的数量。参数 size 用于定义包含太阳系的立方体的大小:

定义 SolarSystem 类的 __init__() 方法,其中包含参数。 size 。您还定义了 bodies 属性。这个属性是一个空列表,当你稍后创建它们时,它将包含太阳系内的所有天体。这个 add_body() 方法可以用来将轨道天体添加到太阳系中。

下一步是介绍Matplotlib。属性创建图形和一组轴。 subplots() 在 matplotlib.pyplot :

你打电话 plt.subplots() ,它返回一个图形和一组轴。返回的值分配给属性。 fig 和 ax 。你打电话 plt.subplots() 有以下论点:

您还可以调用该方法。 tight_layout() 。这是 Figure 类在Matplotlib中。此方法减少了图形边缘的边距。

到目前为止,您可以在控制台/REPL中尝试代码:

这给出了一组空的三维轴的图形:

您将使用 size 参数设置此多维数据集的大小。你会回到 SolarSystem 稍后上课。目前,您可以将您的注意力转向定义 SolarSystemBody 班级。

您可以开始创建 SolarSystemBody 类及其 __init__() 方法。我正在截断 SolarSystem 下面代码中的类定义用于显示。在此代码块和以后的代码块中,包含 # ... 指出您之前编写的未显示的代码:

中的参数。 __init__() 方法是:

你也叫 add_body() 方法中定义的 SolarSystem 类将这个天体添加到太阳系中。稍后,您将向 __init__() 方法。

中定义另一个方法。 SolarSystemBody 用其当前的位置和速度移动物体:

这个 move() 方法重新定义 position 属性的 velocity 属性。我们已经讨论过你是如何用任意单位来计算距离和质量的。你也在使用任意的时间单位。每个‘时间单位’将是循环的一个迭代,您将使用它来运行模拟。因此, move() 将身体按一次迭代所需的数量移动,这是一个时间单位。

你们已经创建了Matplotlib结构,它将容纳太阳系及其所有天体。现在,您可以添加一个 draw() 方法 SolarSystemBody 若要在Matplotlib图上显示主体,请执行以下操作。您可以通过绘制一个标记来完成这一任务。

在这样做之前,您需要在 SolarSystemBody 若要控制将绘制的标记的颜色和大小以表示身体,请执行以下操作:

类属性 min_display_size 和 display_log_base 设置参数,以确定您将在3D图上显示的标记的大小。您设置了一个最小的大小,以便您显示的标记不太小,即使对于小的身体也是如此。您将使用对数标度将质量转换为标记大小,并将此对数的基值设置为另一个类属性。

这个 display_size 属性中的实例属性。 __init__() 方法在计算的标记大小和所设置的最小标记大小之间进行选择。为了在这个项目中确定身体的显示大小,你要使用它的质量。

您还可以添加 colour 属性 __init__() ,暂时默认为黑色。

要测试这些新添加的内容,可以在控制台/REPL中尝试以下内容:

第一次呼叫 body.draw() 在原点绘制物体,因为你使用的是太阳系天体的默认位置。打电话给 body.move() 用一个“时间单位”所需的数量移动身体。因为身体的速度是 (1, 1, 1) ,身体将沿着三个轴中的每一个移动一个单位。第二次呼叫 body.draw() 在第二个位置画太阳系天体。请注意,当您这样做时,轴将自动重新排列。您很快就会在主代码中处理这个问题。

您可以返回到 SolarSystem 通过给太阳系及其天体添加两种新的方法,将其分类和连接起来: update_all() 和 draw_all() :

这个 update_all() 方法穿过太阳系中的每一个物体,移动并画出每一个物体。这个 draw_all() 方法使用太阳系的大小设置三轴的限制,并通过 pause() 功能。此方法还清除轴,为下一个绘图做好准备。

您可以开始构建一个简单的太阳系,并通过创建一个名为 simple_solar_system.py :

运行此脚本时,您将看到一个黑体从情节的中心移动:

您可以更改三维图形的透视图,这样您就可以直接沿着其中一个轴查看3D轴。可以通过将视图的方位和仰角设置为 0 在……里面 SolarSystem.__init__() :

跑动 simple_solar_system.py 现在给出以下观点:

这个 x -轴现在垂直于你的屏幕。因为你在2D显示器上显示一个3D视图,所以你总是有一个方向与你用来显示图形的2D平面垂直。这一限制使得很难区分物体何时沿该轴运动。你可以通过改变身体的速度 simple_solar_system.py 到 (1, 0, 0) 并再次运行脚本。身体似乎是静止的,因为它只是沿着轴移动,从你的屏幕出来!

您可以通过根据它的不同更改标记的大小来改进三维可视化。 x -协调。靠近您的对象看起来更大,而更远的对象看起来更小。您可以对 draw() 方法中的 SolarSystemBody 班级:

self.position[0] 表示身体的位置。 x -轴,即垂直于屏幕的轴。因子 30 除以是一个任意因素,您可以使用它来控制您希望这种效果有多强。

在本教程的后面,您还将添加另一个功能,将有助于可视化的三维运动的恒星和行星。

你有一个太阳系,里面有可以移动的物体。到目前为止,如果您只有一个身体,那么代码可以正常工作。但那不是一个非常有趣的太阳系!如果你有两个或两个以上的物体,它们就会通过相互的引力相互作用。

在这篇文章的开头,我简要回顾了你需要处理两个物体之间的引力的物理。由于在这个项目中使用的是任意单位,所以可以忽略引力常数 G 简单地计算出由于两个物体之间的重力而产生的力,如:

一旦你知道了两个物体之间的力,因为F=ma,您可以计算出每个对象必须使用的加速度:

一旦你知道加速度,你就可以改变物体的速度。

您可以添加两个新方法,一个在 SolarSystemBody 另一个在 SolarSystem ,计算出任何两个物体之间的力和加速度,并穿过太阳系中的所有物体,并计算它们之间的相互作用。

第一种方法计算出两个物体之间的引力,计算每个物体的加速度,并改变两个物体的速度。如果您愿意,可以将这些任务分为三种方法,但在本例中,我将将这些任务放在 SolarSystemBody :

accelerate_e_to_gravity() 对类型的对象调用。 SolarSystemBody 需要另一个 SolarSystemBody 身体作为一种争论。参数 self 和 other 代表两个身体相互作用。此方法的步骤如下:

现在你可以计算出任何两个天体之间的相互作用,你可以计算出太阳系中所有天体之间的相互作用。你可以把你的注意力转移到 SolarSystem 类的类:

这个 calculate_all_body_interactions() 方法贯穿太阳系的所有天体。每个天体与太阳系中的其他天体相互作用:

现在,您已经准备好创建一个简单的太阳系,并测试您到目前为止编写的代码。

在这个项目中,您将关注创建两种类型的天体之一:太阳和行星。您可以为这些机构创建两个类。新类继承自 SolarSystemBody :

这个 Sun 类的默认质量为10,000个单位,并将颜色设置为黄色。使用字符串 'yellow' ,这是Matplotlib中的有效颜色。

在 Planet 类创建一个 itertools.cycle 对象有三种颜色。在这种情况下,这三种颜色是红色、绿色和蓝色。你可以使用你想要的任何RGB颜色,也可以使用任意数量的颜色。在这个类中,使用带有RGB值的元组来定义颜色,而不是使用颜色名称的字符串。这也是在Matplotlib中定义颜色的有效方法。使用 next() 每当你创建一个新的行星时。

您还将默认质量设置为10个单元。

现在,你可以创建一个太阳系,其中一个太阳和两个行星在 simple_solar_system.py :

在这个脚本中,您创建了一个太阳和两个行星。你把太阳和行星分配给变量 sun 和 planets ,但这并不是严格要求的,因为 Sun 和 Planet 对象被创建,它们被添加到 solar_system 你不需要直接引用它们。

你用一个 while 循环来运行模拟。循环在每次迭代中执行三个操作。运行此脚本时,将获得以下动画:

它起作用了,算是吧。你可以看到太阳锚定在这个太阳系的中心,行星受到太阳引力的影响。除了行星在包含你电脑屏幕的平面上的运动(这些是 y -和 z --轴),你也可以看到行星越来越大,因为它们也在 x -轴,垂直于屏幕。

然而,你可能已经注意到行星的一些奇怪的行为。当它们被安排在太阳后面时,行星仍然被展示在太阳的前面。这不是数学上的问题--如果你跟踪行星的位置,你会发现 x -坐标显示,它们实际上是在太阳后面,正如你所预料的那样。

这个问题来自Matplotlib在绘图中绘制对象的方式。Matplotlib按绘制对象的顺序将对象按层绘制。因为你在行星之前创造了太阳, Sun 对象放在第一位 solar_system.bodies 并作为底层绘制。您可以通过在行星之后创建太阳来验证这一事实,在这种情况下,您将看到行星总是出现在太阳后面。

你会希望Matplotlib按照正确的顺序绘制太阳系的天体,从最前的那些天体开始。要实现这一点,您可以对 SolarSystem.bodies 的值为基础的列表。 x -协调每次刷新3D图形的时间。下面是如何在 update_all() 方法 SolarSystem :

使用List方法 sort 带着 key 参数来定义要用于排序列表的规则。这个 lambda 函数设置此规则。在本例中,您使用的值是 position[0] 表示 x -协调。因此,每次你打电话 update_all() 在模拟中 while 循环中,根据其沿 x -轴心。

运行 simple_solar_system.py 现在的脚本如下:

现在,你可以想象行星的轨道,就像它们围绕太阳运行一样。不断变化的大小显示了它们的 x -位置,当行星在太阳后面时,它们被隐藏在视线之外!

最后,你也可以移除轴线和网格,这样你在模拟中看到的就是太阳和行星。可以通过添加对Matplotlib的调用来做到这一点。 axis() 方法 SolarSystem.draw_all() :

模拟现在看起来是这样的:

使用Matplotlib对Python中的一个三维太阳系进行的模拟现在已经完成。在下一节中,您将添加一个功能,允许您查看 XY -模拟底部的飞机。这有助于可视化太阳系中物体的三维动力学。

在Python的三维太阳系模拟中,为了帮助可视化身体的运动,您可以在动画的“地板”上添加一个2D投影。这个2D投影将显示物体在 XY -飞机。要实现这一点,您需要将另一个绘图添加到显示动画的相同轴上,并且只需在 x -和 y -坐标。你可以锚定 z -与图形底部协调,使2D投影显示在动画的地板上。

您可以首先将一个新参数添加到 __init__() 方法的 SolarSystem 班级:

新参数 projection_2d ,默认为 False ,将允许您在两个可视化选项之间切换。如果 projection_2d 是 False 动画将只显示身体在3D中移动,没有轴和网格,就像你最后看到的结果一样。

让我们开始做一些改变 projection_2d 是 True :

您所做的更改如下:

您还需要在 simple_solar_system.py 打开2D投影:

模拟现在看起来如下:

的二维投影 XY -平面使它更容易跟随轨道物体的路径。

我们将用Python完成另一个三维太阳系的模拟。您将使用已经定义的类来模拟双星系统。创建一个名为 binary_star_system.py 创造两个太阳和两个行星:

7. 花了2万多买的Python70个项目,现在分享给大家,练手进厂靠它了

前言:

不管学习哪门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说大家都知道学编程语言一定要做项目才行。

这里整理了70个Python实战项目列表,都有完整且详细的教程,你可以从中选择自己想做的项目进行参考学习练手,你也可以从中寻找灵感去做自己的项目。

1、【Python 图片转字符画】

2、【200行Python代码实现2048】

3、【Python3 实现火车票查询工具】

4、【高德API+Python解决租房问题 】

5、【Python3 色情图片识别】

6、【Python 破解验证码】

7、【Python实现简单的Web服务器】

8、【pygame开发打飞机 游戏 】

9、【Django 搭建简易博客】

10、【Python基于共现提取《釜山行》人物关系】

11、【基于scrapy爬虫的天气数据采集(python)】

12、【Flask 开发轻博客】

13、【Python3 图片隐写术】

14、【Python 实现简易 Shell】

15、【使用 Python 解数学方程】

16、【PyQt 实现简易浏览器】

17、【神经网络实现手写字符识别系统 】

18、【Python 实现简单画板】

19、【Python实现3D建模工具】

20、【NBA常规赛结果预测——利用Python进行比赛数据分析】

21、【神经网络实现人脸识别任务】

22、【Python文本解析器】

23、【Python3 & OpenCV 视频转字符动画】

24、【Python3 实现淘女郎照片爬虫 】

25、【Python3实现简单的FTP认证服务器】

26、【基于 Flask 与 MySQL 实现番剧推荐系统】

27、【Python 实现端口扫描器】

28、【使用 Python 3 编写系列实用脚本】

29、【Python 实现康威生命 游戏 】

30、【川普撞脸希拉里(基于 OpenCV 的面部特征交换) 】

31、【Python 3 实现 Markdown 解析器】

32、【Python 气象数据分析 -- 《Python 数据分析实战》】

33、【Python实现键值数据库】

34、【k-近邻算法实现手写数字识别系统】

35、【ebay在线拍卖数据分析】

36、【Python 实现英文新闻摘要自动提取 】

37、【Python实现简易局域网视频聊天工具】

38、【基于 Flask 及爬虫实现微信 娱乐 机器人】

39、【Python实现Python解释器】

40、【Python3基于Scapy实现DDos】

41、【Python 实现密码强度检测器】

42、【使用 Python 实现深度神经网络】

43、【Python实现从excel读取数据并绘制成精美图像】

44、【人机对战初体验:Python基于Pygame实现四子棋 游戏 】

45、【Python3 实现可控制肉鸡的反向Shell】

46、【Python打造漏洞扫描器 】

47、【Python应用马尔可夫链算法实现随机文本生成】

48、【数独 游戏 的Python实现与破解】

49、【使用Python定制词云】

50、【Python开发简单计算器】

51、【Python 实现 FTP 弱口令扫描器】

52、【Python实现Huffman编码解压缩文件】

53、【Python实现Zip文件的暴力破解 】

54、【Python3 智能裁切图片】

55、【Python实现网站模拟登陆】

56、【给Python3爬虫做一个界面.妹子图网实战】

57、【Python 3 实现图片转彩色字符】

58、【自联想器的 Python 实现】

59、【Python 实现简单滤镜】

60、【Flask 实现简单聊天室】

61、【基于PyQt5 实现地图中定位相片拍摄位置】

62、【Python实现模板引擎】

63、【Python实现遗传算法求解n-queens问题】

64、【Python3 实现命令行动态进度条】

65、【Python 获取挂号信息并邮件通知】

66、【Python实现java web项目远端自动化更新部署】

67、【使用 Python3 编写 Github 自动周报生成器】

68、【使用 Python 生成分形图片】

69、【Python 实现 Redis 异步客户端】

70、【Python 实现中文错别字高亮系统】

最后:

以上项目列表希望可以给你在Python学习中带来帮助~

获取方式:转发 私信“1”

8. python爬虫能干什么

python爬虫就是模拟浏览器打开网页,获取网页中想要的那部分数据。利用爬虫我们可以抓取商品信息、评论及销量数据;可以抓取房产买卖及租售信息;可以抓取各类职位信息等。

爬虫:

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

(推荐教程:Python入门教程)

通俗的讲就是通过程序去获取web页面上自己想要的数据,也就是自动抓取数据。

python爬虫能做什么?

从技术层面来说就是通过程序模拟浏览器请求站点的行为,把站点返回的HTML代码/JSON数据/二进制数据(图片、视频) 爬到本地,进而提取自己需要的数据存放起来使用。

利用爬虫我们可以获取大量的价值数据,从而获得感性认识中不能得到的信息,比如:

爬取知乎优质答案,为你筛选出各话题下最优质的内容。

抓取淘宝、京东商品、评论及销量数据,对各种商品及用户的消费场景进行分析。

抓取房产买卖及租售信息,分析房价变化趋势、做不同区域的房价分析。

爬取各类职位信息,分析各行业人才需求情况及薪资水平。

爬虫的本质:

爬虫的本质就是模拟浏览器打开网页,获取网页中我们想要的那部分数据。

阅读全文

与python能模拟出地层吗相关的资料

热点内容
阿里云服务器能连接打印机吗 浏览:169
命令行参考 浏览:279
怎么初步认识编程 浏览:208
为什么程序员都喜欢谷歌 浏览:891
压缩性骨拆能自愈吗 浏览:277
安卓怎么设置游戏画面 浏览:114
k线上写字源码 浏览:457
单击按钮保存资料源码 浏览:354
华为gt加密卡 浏览:213
河北超融合服务器厂家云主机 浏览:894
芙儿优安全座椅app怎么连接 浏览:294
专业美团骑手app怎么开通 浏览:949
个人音乐分享网站源码 浏览:375
在新电脑上怎么注册加密狗 浏览:123
最后一战游戏源码 浏览:5
phpmysql实例下载 浏览:751
传智黑马安卓非加密 浏览:553
服务器如何配置host 浏览:1001
守望执行命令 浏览:371
加密狗插上去了怎么办 浏览:624