简介
将project迁移到新的编程语言可能是一项困难且耗时的任务。 GitHub Copilot 通过说明需要做出的更改,并建议使用新语言替换代码,从而帮助你完成此过程。
将项目迁移到新语言的原则
在开始迁移过程之前,请考虑以下几点:
-
编码知识
请确保充分了解这两种编程语言。 虽然 Copilot 可以为你翻译代码,但你需要了解它建议的选项,并决定是否要使用其建议或请求替代建议。
-
要迁移的系统的知识
不仅要了解当前系统的功能和特性,还应了解它的体系结构和逻辑。 必须能够检查转换后的代码是否执行与原始代码相同的操作并产生相同的结果。
-
使用 AI 帮助你
如果你不理解即将翻译的代码中的某一部分,可以使用 Copilot 的“解释”功能,对整个文件使用,或对文件中选定的部分代码使用。 请参阅 在 IDE 中向 GitHub Copilot 提问问题。
-
计划完成迁移的时间
转换是一个多阶段过程。 项目越大,所需的转换步骤就越多。 请确保有足够的时间完成整个过程。
-
迭代工作
旨在单独转换项目的各个独立部分。 在转到project的另一部分之前,请确保已验证你所做的所有更改。 在项目进行过程中,为各个部分编写测试,以便确认每个新组件能够按预期运行。
-
避免在该过程增加复杂性
最初你应目标是进行一对一转换。 在您的项目中,并非所有代码都能实现这一点。 但是,为了避免给迁移任务增加复杂性,除转换代码以及使用新框架和适当的依赖项之外,应尽量限制引入的新更改数量。
-
对转换后的代码进行基准测试和重构
完成初始转换并拥有可用系统后,可以执行基准测试来比较旧系统和新系统。 现在可以使用新语言重构代码。 这是优化代码并减少技术债务的机会。
使用 Copilot 帮助你将项目迁移到新的编程语言
假设你已经熟悉了现有项目,启动迁移的一个好方法是在编辑器中打开存储库的分支并寻求帮助 Copilot 。
-
在编辑器中,打开副驾驶聊天面板。 请参阅 在 IDE 中向 GitHub Copilot 提问问题。
-
要求 Copilot 概述将项目迁移到新语言所需的步骤。
例如,如果要从 PHP 迁移到 Python,可以这样询问:
Copilot prompt @workspace I want to migrate this project from PHP to Python. Give me a high-level overview of the steps I need to take. Don't go into detail at this stage.
@workspace I want to migrate this project from PHP to Python. Give me a high-level overview of the steps I need to take. Don't go into detail at this stage.注意
@workspace聊天参与者将当前工作区中的文件设置为所提的问题的上下文。
Copilot 通常会返回一个你需要执行的项目迁移步骤列表。
-
复制 Copilot的响应并将其保存在某个位置以在整个过程中引用。
-
请完成该过程的每个步骤,并在需要时请求详细的帮助 Copilot 。
仔细考虑来自 Copilot 的每一条建议。 请确保你了解它建议的代码,并评估它是否适合你的project。 如果不确定,请要求 Copilot 向你解释代码。
如果你认为建议的 Copilot 更改在某些方面是不对的,请提出另一种建议。
-
将组件迁移到可以运行的状态后,请检查它是否按预期工作。 如果生成错误,请将错误 副驾驶聊天 复制到视图中,并请求 Copilot 帮助修复错误。
-
完成初始转换后,用于 Copilot 帮助你用新语言重构代码。 有关详细信息,请参阅 使用 GitHub Copilot 重构代码。
示例:将 PHP project迁移到 Python
以下示例介绍了将简单的 Web 应用程序从 PHP 迁移到 Python 的过程。 即使这些编程语言不是你正在使用的迁移语言,遵循此处描述的步骤以熟悉项目迁移过程也是很有帮助的。 将其他小项目从一种语言迁移到另一种语言时,步骤将类似。

此示例假定:
- 你正在Visual Studio Code中工作。
- 你已安装两种语言:PHP 和 Python 版本 3.12 或更高版本。
迁移一个简单的网站项目
我们将在此公共存储库 GitHub中迁移代码: docs/simple-php-website。
此仓库包含以下文件。
.gitignore
.htaccess
LICENSE
content
├── 404.phtml
├── about-us.phtml
├── contact.phtml
├── home.phtml
└── products.phtml
includes
├── config.php
└── functions.php
index.php
readme.md
template
├── style.css
└── template.php
此示例给出了可在 副驾驶聊天 中输入以完成迁移的提示词,以及在该迁移的一个实例中 Copilot 返回的响应。 该 GPT-4.1 模型用于生成这些响应。 副驾驶聊天 响应是不确定的,因此你可能会得到此处所示的响应略有不同。
在迁移过程中,你可能会遇到需要修复的错误,只有在解决这些错误后才能继续进行。 Copilot 可以帮助你解决此问题。 该示例包含一些错误,并演示如何让 Copilot 帮助你修复这些错误。
由于你从 副驾驶聊天 中获取的响应可能与此处所示的响应不同,因此可能会遇到不同的错误。 因此,你可能会发现,使用此处显示的响应来逐步完成这个迁移示例,比使用你自己从 Copilot 获得的响应更容易。
完成此示例迁移后,可以在自己的project使用相同的方法。
-
首先,将仓库的副本克隆到本地计算机。
-
运行应用程序以验证其是否正常运行。
要做到这一点,请在终端中导航到克隆的存储库的根目录,并运行以下命令:
Shell php -S localhost:8000
php -S localhost:8000然后在浏览器中转到 http://localhost:8000。
-
浏览一下网站,熟悉其结构,这样你就能验证迁移是否成功。
-
在存储库中创建工作分支,并将其作为新工作区打开 Visual Studio Code。
-
熟悉现有项目的内容和体系结构。 Copilot 可帮助你做到这一点:
-
打开副驾驶聊天视图。
-
输入提示,例如:
Copilot prompt @workspace Describe this project in detail, explaining what the various components do and how they interact.
@workspace Describe this project in detail, explaining what the various components do and how they interact.
-
-
要求 Copilot 大致了解迁移过程:
Copilot prompt @workspace I want to migrate this project from PHP to Python. Give me a high-level overview of the steps I need to take. Don't go into detail at this stage.
@workspace I want to migrate this project from PHP to Python. Give me a high-level overview of the steps I need to take. Don't go into detail at this stage.
Copilot 将回复如下说明:
To migrate this project from PHP to Python, follow these high-level steps:
1. Set Up Python Environment:
- Install Python and set up a virtual environment.
- Install necessary packages (e.g., Flask for web framework).
2. Convert Configuration:
- Translate the configuration settings from config.php to a Python configuration file.
3. Rewrite Functions:
- Convert PHP functions in functions.php to Python functions.
4. Create Flask Application:
- Set up a Flask application to handle routing and views.
- Map the routes to corresponding views.
5. Convert Templates:
- Translate template.php to a Jinja2 template.
- Update the CSS file path in the template.
6. Convert Content Pages:
- Convert .phtml content files to HTML or Jinja2 templates.
7. Update .htaccess Rules:
- Translate .htaccess rewrite rules to Flask route handling.
8. Run and Test:
- Run the Flask application and test all routes and functionalities.
- Ensure the site works as expected and fix any issues.
9. Documentation:
- Update the readme.md with new instructions for running the Python project.
-
复制 Copilot的响应并将其保存在某个位置,以在整个此过程的其余部分中引用。 你将逐一完成这些步骤,并在操作过程中向 Copilot 寻求帮助。
-
如果尚未确定要使用的Python框架,可以征求Copilot意见:
Copilot prompt @workspace What Python frameworks can I use for this project once it is migrated to Python? Give me a selection of options, with a brief summary of the pros and cons of each in relation to this website project. Which framework would you recommend?
@workspace What Python frameworks can I use for this project once it is migrated to Python? Give me a selection of options, with a brief summary of the pros and cons of each in relation to this website project. Which framework would you recommend?
Copilot 回复有关各种框架的信息,并总结如下:
For a project like yours - which is a simple, content-driven website - Flask is highly recommended. Its simplicity, flexibility, and ease of use (especially with its templating system that can easily replace your current PHP template structure) make it a great fit.
我们将采纳 Copilot 的建议并使用 Flask。
-
Copilot返回到“高级概述”,第一步是设置Python环境并安装所需的包。 若要了解如何执行此操作,请输入 副驾驶聊天:
Copilot prompt @workspace I want to use Flask. Tell me how to set up a virtual environment and install the necessary packages.
@workspace I want to use Flask. Tell me how to set up a virtual environment and install the necessary packages.
Copilot 将回复如下说明:
1. Create a virtual environment:
- Open a terminal and navigate to your project directory.
- Run the following command to create a virtual environment:
python3 -m venv venv
2. Activate the virtual environment:
- On macOS and Linux:
source venv/bin/activate
- On Windows:
venv\Scripts\activate
3. Install Flask and necessary packages:
- With the virtual environment activated, run the following command
to install Flask and other necessary packages:
pip install Flask
4. Verify the installation:
- You can verify that Flask is installed by running:
pip list
-
按照 Copilot 的说明操作,并使用
pip list来验证 Flask 是否已安装。 -
返回迁移 Copilot过程的概述,下一步是转换配置。 就此向 Copilot 求助。 例如:
Copilot prompt @workspace As the first step in migrating this project from PHP to Python, create a Python configuration file by converting the functions in functions.php to Python functions. Tell me where to locate the Python config file in the project.
@workspace As the first step in migrating this project from PHP to Python, create a Python configuration file by converting the functions in functions.php to Python functions. Tell me where to locate the Python config file in the project.
Copilot建议你在includes目录中创建一个名为config.py的文件,其中包含以下代码。
config = {
'name': 'Simple Python Website',
'site_url': '',
'pretty_uri': False,
'nav_menu': {
'': 'Home',
'about-us': 'About Us',
'products': 'Products',
'contact': 'Contact',
},
'template_path': 'template',
'content_path': 'content',
'version': 'v3.1',
}
def get_config(key=''):
return config.get(key, None)
def site_name():
return get_config('name')
def site_url():
return get_config('site_url')
def site_version():
return get_config('version')
def nav_menu(sep=' | '):
nav_menu = ''
nav_items = get_config('nav_menu')
for uri, name in nav_items.items():
query_string = request.args.get('page', '')
class_active = ' active' if query_string == uri else ''
url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
return nav_menu.strip(sep)
def page_title():
page = request.args.get('page', 'Home')
return ' '.join(word.capitalize() for word in page.split('-'))
def page_content():
page = request.args.get('page', 'home')
path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
if not os.path.exists(path):
path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
with open(path, 'r') as file:
return file.read()
def init():
template_path = os.path.join(get_config('template_path'), 'template.html')
with open(template_path, 'r') as file:
return file.read()
config = {
'name': 'Simple Python Website',
'site_url': '',
'pretty_uri': False,
'nav_menu': {
'': 'Home',
'about-us': 'About Us',
'products': 'Products',
'contact': 'Contact',
},
'template_path': 'template',
'content_path': 'content',
'version': 'v3.1',
}
def get_config(key=''):
return config.get(key, None)
def site_name():
return get_config('name')
def site_url():
return get_config('site_url')
def site_version():
return get_config('version')
def nav_menu(sep=' | '):
nav_menu = ''
nav_items = get_config('nav_menu')
for uri, name in nav_items.items():
query_string = request.args.get('page', '')
class_active = ' active' if query_string == uri else ''
url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
return nav_menu.strip(sep)
def page_title():
page = request.args.get('page', 'Home')
return ' '.join(word.capitalize() for word in page.split('-'))
def page_content():
page = request.args.get('page', 'home')
path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
if not os.path.exists(path):
path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
with open(path, 'r') as file:
return file.read()
def init():
template_path = os.path.join(get_config('template_path'), 'template.html')
with open(template_path, 'r') as file:
return file.read()
-
创建
includes/config.py文件并删除现有的includes/config.php文件。 -
再次返回到概述,请求 Copilot 帮助你重写 PHP 函数。
Copilot prompt @workspace Continuing the migration of this project from PHP to Python, create Python functions to replace the existing PHP functions. Tell me where to locate the Python functions in the project.
@workspace Continuing the migration of this project from PHP to Python, create Python functions to replace the existing PHP functions. Tell me where to locate the Python functions in the project.
Copilot建议您在includes目录中创建一个名为functions.py的文件,其中包含以下代码。
import os
from flask import request
from .config import get_config
def site_name():
return get_config('name')
def site_url():
return get_config('site_url')
def site_version():
return get_config('version')
def nav_menu(sep=' | '):
nav_menu = ''
nav_items = get_config('nav_menu')
for uri, name in nav_items.items():
query_string = request.args.get('page', '')
class_active = ' active' if query_string == uri else ''
url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
return nav_menu.strip(sep)
def page_title():
page = request.args.get('page', 'Home')
return ' '.join(word.capitalize() for word in page.split('-'))
def page_content():
page = request.args.get('page', 'home')
path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
if not os.path.exists(path):
path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
with open(path, 'r') as file:
return file.read()
def init():
template_path = os.path.join(get_config('template_path'), 'template.html')
with open(template_path, 'r') as file:
return file.read()
import os
from flask import request
from .config import get_config
def site_name():
return get_config('name')
def site_url():
return get_config('site_url')
def site_version():
return get_config('version')
def nav_menu(sep=' | '):
nav_menu = ''
nav_items = get_config('nav_menu')
for uri, name in nav_items.items():
query_string = request.args.get('page', '')
class_active = ' active' if query_string == uri else ''
url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
return nav_menu.strip(sep)
def page_title():
page = request.args.get('page', 'Home')
return ' '.join(word.capitalize() for word in page.split('-'))
def page_content():
page = request.args.get('page', 'home')
path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
if not os.path.exists(path):
path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
with open(path, 'r') as file:
return file.read()
def init():
template_path = os.path.join(get_config('template_path'), 'template.html')
with open(template_path, 'r') as file:
return file.read()
-
创建
includes/functions.py文件并删除现有的includes/functions.php文件。 -
继续处理概述内容,下一步是创建 Flask 应用程序。 请让 Copilot 帮助你解决这个问题:
Copilot prompt @workspace Set up a Flask application to handle routing and views, and map the routes to corresponding views. Tell me the location of any files that need to be created or changed.
@workspace Set up a Flask application to handle routing and views, and map the routes to corresponding views. Tell me the location of any files that need to be created or changed.
Copilot 建议在项目的根目录中创建一个调用 app.py 的文件,其中包含以下代码。
from flask import Flask, render_template, request
import os
app = Flask(__name__)
config = {
'name': 'Simple Python Website',
'site_url': '',
'pretty_uri': False,
'nav_menu': {
'': 'Home',
'about-us': 'About Us',
'products': 'Products',
'contact': 'Contact',
},
'template_path': 'template',
'content_path': 'content',
'version': 'v3.1',
}
def get_config(key=''):
return config.get(key, None)
@app.route('/')
@app.route('/<page>')
def index(page='home'):
page_content = get_page_content(page)
page_title = get_page_title(page)
nav_menu = get_nav_menu()
return render_template('template.html', page_title=page_title, page_content=page_content, nav_menu=nav_menu)
def get_page_title(page):
return ' '.join(word.capitalize() for word in page.split('-'))
def get_page_content(page):
path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
if not os.path.exists(path):
path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
with open(path, 'r') as file:
return file.read()
def get_nav_menu(sep=' | '):
nav_menu = ''
nav_items = get_config('nav_menu')
for uri, name in nav_items.items():
query_string = request.args.get('page', '')
class_active = ' active' if query_string == uri else ''
url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
return nav_menu.strip(sep)
if __name__ == '__main__':
app.run(debug=True)
from flask import Flask, render_template, request
import os
app = Flask(__name__)
config = {
'name': 'Simple Python Website',
'site_url': '',
'pretty_uri': False,
'nav_menu': {
'': 'Home',
'about-us': 'About Us',
'products': 'Products',
'contact': 'Contact',
},
'template_path': 'template',
'content_path': 'content',
'version': 'v3.1',
}
def get_config(key=''):
return config.get(key, None)
@app.route('/')
@app.route('/<page>')
def index(page='home'):
page_content = get_page_content(page)
page_title = get_page_title(page)
nav_menu = get_nav_menu()
return render_template('template.html', page_title=page_title, page_content=page_content, nav_menu=nav_menu)
def get_page_title(page):
return ' '.join(word.capitalize() for word in page.split('-'))
def get_page_content(page):
path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
if not os.path.exists(path):
path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
with open(path, 'r') as file:
return file.read()
def get_nav_menu(sep=' | '):
nav_menu = ''
nav_items = get_config('nav_menu')
for uri, name in nav_items.items():
query_string = request.args.get('page', '')
class_active = ' active' if query_string == uri else ''
url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
return nav_menu.strip(sep)
if __name__ == '__main__':
app.run(debug=True)
Copilot还建议重命名template/template.php``template/template.html并更新文件以使用 Jinja2 模板语法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<title>{{ page_title }} | {{ get_config('name') }}</title>
<link href="{{ get_config('site_url') }}/template/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="wrap">
<header>
<h1>{{ get_config('name') }}</h1>
<nav class="menu">
{{ nav_menu|safe }}
</nav>
</header>
<article>
<h2>{{ page_title }}</h2>
{{ page_content|safe }}
</article>
<footer>
<small>©{{ get_config('version') }} {{ get_config('name') }}.<br>{{ get_config('version') }}</small>
</footer>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<title>{{ page_title }} | {{ get_config('name') }}</title>
<link href="{{ get_config('site_url') }}/template/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="wrap">
<header>
<h1>{{ get_config('name') }}</h1>
<nav class="menu">
{{ nav_menu|safe }}
</nav>
</header>
<article>
<h2>{{ page_title }}</h2>
{{ page_content|safe }}
</article>
<footer>
<small>©{{ get_config('version') }} {{ get_config('name') }}.<br>{{ get_config('version') }}</small>
</footer>
</div>
</body>
</html>
-
按照建议创建
app.py和template/template.html文件。 -
Copilot 还可以建议,创建这些文件后,现在从存储库的根目录在终端中运行
python app.py,然后浏览到 http://127.0.0.1:5000。注意
根据计算机上安装 Python 的方式,可能需要使用命令
python3 app.py而不是python app.py,以确保使用正确的 Python 版本。执行此操作时,浏览器中会显示错误消息。
-
将初始
TemplateNotFound错误消息复制到 副驾驶聊天 视图,并询问如何解决此问题。 例如:Copilot prompt @workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.TemplateNotFound: template.html`. How can I fix this?
@workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.TemplateNotFound: template.html`. How can I fix this?
Copilot 答复错误指示 Flask 找不到 template.html 文件。
它告诉你,Flask 默认在project根目录中的名为 templates 的文件夹中查找模板。 但 template.html 文件位于 template 目录中。 要解决此问题,需要在创建 Flask 应用时指定正确的模板文件夹。 它会建议你更新 app.py 文件,更改分配 app = Flask(__name__) 以包括 template_folder 参数:
app = Flask(__name__, template_folder='template')
app = Flask(__name__, template_folder='template')
-
假设 Flask 开发服务器仍在运行,如果刷新浏览器页面 (http://127.0.0.1:5000/),则现在会看到与
get_config函数相关的新错误。将此错误消息复制到 副驾驶聊天 视图并寻求帮助。
Copilot prompt @workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.UndefinedError: 'get_config' is undefined.` How can I fix this?
@workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.UndefinedError: 'get_config' is undefined.` How can I fix this?
Copilot 答复错误发生是因为 get_config 在 Jinja2 模板上下文中不可用。 它建议将以下代码添加到 app.py 文件,直接放在第 @app.route('/') 行前面:
app.jinja_env.globals.update(get_config=get_config)
app.jinja_env.globals.update(get_config=get_config)
-
刷新浏览器,现在应会看到该网站。

但是,未应用任何 CSS 样式。 稍后我们将解决此问题。
-
问 Copilot:
Copilot prompt @workspace The deployed website does not use the CSS styles. How can I fix this?
@workspace The deployed website does not use the CSS styles. How can I fix this?
Copilot 告诉你,Flask 预期你的 CSS 文件位于名为 static 的目录中。 它建议将现有 style.css 文件从 template 目录移动到新的 static 目录中,然后更新 style.css 文件的 head 部分中 template.html 文件的路径。 更改为:
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
刷新浏览器后,网站现在应会正确呈现。
若要完成初始迁移,请继续完成提供的高级概述 Copilot 中的步骤,根据需要寻求帮助。
完成迁移
成功完成迁移过程的进一步工作涉及以下内容:
- 彻底检查初始迁移****。
- 修复 Bug ****。 例如,在此处所述的示例中,只有在
pretty_uri文件的True部分,将config设置为app.py时,页面链接才会有效。 如果想要在页面 URL 中使用查询字符串参数的选项,或者想要从代码中删除此选项,可以请求 Copilot 帮助执行此操作。 - 为已迁移的项目编写测试。
- 清理项目,通过删除任何不再需要的文件。
- 使用新语言重构代码****。 迁移过程产生了一个Python项目,其体系结构基于原始PHP项目。 完成初始迁移后,现在可以重构代码,充分利用 Python 语言和 Flask 框架的功能。
- 更新文档。
readme.md文件现已过期,需要重写。