标签 python 下的文章

开源开发的理念使得 Anvil 的整个解决方案更加有用且值得信赖。

 title=

Anvil 团队最近开源了 Anvil App Server, 一个用于托管完全用 Python 构建的 Web 程序的运行时引擎。

社区的反应十分积极,我们 Anvil 团队已经将许多反馈纳入了我们的 下一个版本。但是我们不断被问到的问题是,“为什么你们选择开源这个产品的核心呢?”

我们为何创造 Anvil

Anvil 是一个可以使得构建 Web 应用更加简单的工具。我们让你们有能力仅使用一种语言—— Python —— 就可以来构建你的整个应用。

在 Anvil 之前,如果你想要构建一个 Web app,你需要写很多代码,用很多的技术,比如 HTML、Javascript、CSS、Python、SQL、React、Redux、Bootstrap、Sass、Webpack 等。这需要花费很长时间来学习。对于一个简单的应用便是这样子;相信我,一般的应用其实 更加复杂

 title=

是的。对于一个简单的 web 应用便是需要如此多的技术。

但即使如此,你还没有完成!你需要了解有关 Git 和云托管提供商的所有信息、如何保护(很有可能是)Linux 操作系统、如何调整数据库,然后随时待命以保持其运行。一直如此。

因此,我们开发出了 Anvil,这是一个在线 IDE,你可以在用 拖放编辑器 来设计你的 UI 界面,用 Python 编写你的 逻辑,然后 Anvil 会负责其余的工作。我们将所有的繁杂的技术栈进行了替换,只用 Python 就行啦!

简单的 Web 托管很重要,但还不够

Anvil 还可以为你托管你的应用程序。为什么不呢?部署 Web 应用程序非常复杂,因此运行我们自己的云托管服务是提供我们所需的简单性的唯一方法。在 Anvil 编辑器中构建一个应用程序,单击按钮,它就在网上发布了。

但我们不断听到有人说,“那太好了,但是……”

  • “我需要在没有可靠互联网接入的海外平台上运行这个应用。”
  • “我想要将我的应用程序嵌入到我售出的 IoT 设备中”
  • "如果我把我的宝都压到你的 Anvil 上,我怎么能确定十年后我的应用仍然能够运行呢?”

这些都是很好的观点!云服务并不是适合所有人的解决方案。如果我们想为这些用户提供服务,就必须有一些方法让他们把自己的应用从 Anvil 中取出来,在本地运行,由他们自己完全控制。

开源是一个逃生舱,而不是弹射座椅

在会议上,我们有时会被问到,“我可以将它导出为 Flask+JS 的应用程序吗?” 当然,我们可以将 Anvil 项目分别导出为 Python 和 JavaScript —— 我们可以生成一个服务器包,将客户端中的 Python 编译为 Javascript,然后生成一个经典的 Web 应用程序。但它会有严重的缺点,因为:代码生成是一个弹射座椅。

 title=

生成的代码聊胜于无;至少你可以编辑它!但是在你编辑该代码的那一刻,你就失去了生成它的系统的所有好处。如果你使用 Anvil 是因为它的 拖放编辑器运行在浏览器中的 Python,那么你为什么必须使用 vim 和 Javascript 才能在本地托管你的应用程序?

我们相信 逃生舱,而不是弹射座椅。所以我们选择了一个正确的方式——我们 开源了 Anvil 的运行引擎,这与在我们的托管服务中为你的应用程序提供服务的代码相同。这是一个独立的应用程序;你可以使用文本编辑器编辑代码并在本地运行。但是你也可以将它直接用 git 推回到我们的在线 IDE。这不是弹射座椅;没有爆炸性的转变。这是一个逃生舱;你可以爬出来,做你需要做的事情,然后再爬回来。

如果它开源了,它还可靠吗

开源中的一个看似矛盾的是,它的免费可用性是它的优势,但有时也会产生不稳定的感觉。毕竟,如果你不收费,你如何保持这个平台的长期健康运行?

我们正在做我们一直在做的事情 —— 提供一个开发工具,使构建 Web 应用程序变得非常简单,尽管你使用 Anvil 构建的应用程序 100% 是你的。我们为 Anvil 应用程序提供托管,并为 企业客户 提供整个现场开发和托管平台。这使我们能够提供免费计划,以便每个人都可以将 Anvil 用于业余爱好或教育目的,或者开始构建某些东西并查看它的发展。

得到的多,失去的少

开源我们的运行引擎并没有减少我们的业务 —— 它使我们的在线 IDE 在今天和未来变得更有用、更值得信赖。我们为需要它的人开放了 Anvil App Server 的源代码,并提供最终的安全保障。对于我们的用户来说,这是正确的举措 —— 现在他们可以放心地进行构建,因为他们知道开源代码 就在那里,如果他们需要的话。

如果我们的开发理念与你产生共鸣,何不亲自尝试 Anvil?


这篇文章改编自 Why We Open Sourced the Anvil App Server,经许可重复使用。


via: https://opensource.com/article/20/7/why-open-source

作者:Meredydd Luff 选题:lujun9972 译者:zepoch 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

一窥开源 Python 项目保持平稳运行的社区幕后。

 title=

Jannis Leidel 是 Jazzband 社区的一部分。Jazzband 是一个协作社区,共同承担维护基于 Python 的项目。

Jazzband 的诞生源于长期独自维护一个开源项目的压力。Jannis 是“roadie”,这意味着他负责管理任务并确保团队中的人可以在他们想要的时候参与。

Jazzband 并不是他的第一个开源志愿者工作——他是前 Django 核心开发人员,Django 软件基金会 董事会成员,编写了许多 Django 应用程序和 Python 项目,曾是 pipvirtualenv 核心开发人员和发布经理,共同创立了 Python 打包机构 Python Packaging Authority ,还担任过 PyPI 管理员。在社区方面,他共同创立了德国 Django 协会,担任 DjangoCon Europe 2010 联合主席,在多个会议上发言,并在去年担任了 Python 软件基金会 董事和联席主席。

Moshe Zadka: 你是如何开始编程的?

Jannis Leidel:我开始接触编程是在高中的常规德国计算机科学课程中,在那里我涉猎了 Turbo Pascal 和 Prolog。我很快就进入了 Web 开发的世界,并使用 PHP3、Perl5MySQL 编写了一些小型网站。后来在大学里,我在从事媒体艺术项目时再次学习了编程,发现 Ruby、Perl 和 Python 特别有用。我最终坚持使用 Python,因为它的多功能性和易用性。从那时起,我很高兴能够在我的职业生涯中使用 Python 和开放 Web 技术(HTML/JS/CSS)。

Zadka: 你是如何开始接触开源的?

Leidel:作为大学艺术项目的一部分,我需要一种与各种 Web 服务对话并与一些电子设备交互的方法,但发现我之前的 PHP 技能无法胜任这项任务。因此,我参加了有关使用 Python 编程的课程,相比库,我对学习更多有关框架如何工作更感兴趣,因为它们进一步体现了我想了解的最佳实践。特别是,新生的 Django Web 框架对我很有吸引力,因为它倾向于一种务实的方法,并为如何开发 Web 应用程序提供了大量指导。 2007 年,我作为学生参与了 Google Summer of Code for Django,后来为 Django 及其可重用组件生态系统做出了更多贡献,不久我也成为了 Django 核心开发人员。在完成学位期间,我能够利用这些技能成为一名自由职业者,并花时间在 Django 社区的许多不同部分工作。在那时,横向移动到更广泛的 Python 社区不过是很自然的。

Zadka: 你的日常工作是什么?

Leidel:我是 Mozilla 的一名软件工程师,致力于为 Firefox 数据管道开发数据工具。实际上,这意味着我在更广泛的 Firefox 工程团队中工作,从事各种内部和面向公众的基于 Web 的项目,这些项目帮助 Mozilla 员工和社区成员理解 Firefox Web 浏览器发送的遥测数据。我目前的部分重点是维护我们的数据分析和可视化平台,该平台基于开源项目 Redash,并对其做出贡献。我参与的其他项目是我们的下一代遥测系统 Glean 和一个允许你在浏览器(包括 Scientific Python 堆栈)中进行数据科学的工具 Iodide

Zadka: 你是如何参与 Jazzband 的?

Leidel:早在 2015 年,我就对单独维护很多人所依赖的项目感到沮丧,并看到我的许多社区同行都在为类似的问题苦苦挣扎。我不知道有什么好方法可以让社区中更多的人对长期维护感兴趣。在某些情况下,我觉得新的“社会编码”范式的社会性的不足,而且常常是孤立的,有时甚至对新老贡献者来说都是创伤。我相信在我们的社区中,我现在觉得无法容忍的不平等现象在当时更加猖獗,这使得为贡献者提供一个安全的环境变得困难——我们现在知道这对于稳定的项目维护至关重要。我想知道我们是否缺少一种更具协作性和包容性的软件开发方法。

Jazzband 项目的启动是为了降低进入维护的门槛,并简化其中一些较无聊的方面(例如,围绕 CI 的最佳实践)。

Zadka: 你最喜欢 Jazzband 的哪一点?

Leidel:我最喜欢 Jazzband 的一点是,我们确保了许多人所依赖的许多项目的维护,同时还确保任何经验水平的新贡献者都可以加入。

Zadka: Jazzband 的“roadie”的工作是什么?

Leidel:“roadie”是指处理 Jazzband 幕后所有事务的人。这意味着,例如,处理新项目的进入、维护 Jazzband 网站以处理用户管理和项目发布、充当安全或行为准则事件的第一响应者等等。“roadie”这个词是从音乐和演出行业借来的,指的是支持人员,他们负责在巡回演出中几乎所有需要做的事情,除了实际的艺术表演。在 Jazzband,他们的存在是为了确保成员可以在项目中工作。这也意味着,在有意义的情况下,某些任务是部分或完全自动化的,并且最佳实践被应用于大多数 Jazzband 项目,如打包设置、文档托管或持续集成。

Zadka: 作为 Jazzband 的“roadie”,你工作中最具挑战性的方面是什么?

Leidel:目前,我作为“roadie”的工作中最具挑战性的方面是实施社区成员提出的 Jazzband 改进,而不影响他们所依赖的工作流程。换句话说,Jazzband 越大,在概念级别上扩展项目变得越困难。具有讽刺意味的是,我是目前唯一的“roadie”,独自处理一些任务,而 Jazzband 却试图阻止其项目发生这种情况。这是 Jazzband 未来的一大担忧。

Zadka: 对于有兴趣想知道能否加入 Jazzband 的人,你有什么想说的?

Leidel:如果你有兴趣加入一群相信协作工作比单独工作更好的人,或者如果你一直在为自己的维护负担而苦苦挣扎,并且不知道如何继续,请考虑加入 Jazzband。它简化了新贡献者的进入流程,提供了一个争议解决框架,并自动发布到 PyPI。有许多最佳实践可以很好地降低项目无人维护的风险。

Zadka: 你还有什么想告诉我们的读者的吗?

Leidel:我鼓励每个从事开源项目的人都考虑屏幕另一边的人。要有同理心,记住你自己的经历可能不是你同龄人的经历。要明白你是全球多元化社区的成员,这要求我们始终尊重我们之间的差异。


via: https://opensource.com/article/20/2/python-maintained

作者:Moshe Zadka 选题:lujun9972 译者:stevenzdg988 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索最近版本的 Python 的一些有用的特性。

 title=

这是 Python 3.x 首发特性系列文章中的第十篇,其中一些版本已经发布了一段时间。Python 3.9 在 2020 年首次发布,具有很酷的新特性,但仍未被充分利用。下面是其中的三个。

添加字典

假设你有一个 defaults 字典,而你想更新它的参数。在 Python 3.9 之前,最好的办法是复制 defaults 字典,然后使用 .update() 方法。

Python 3.9 为字典引入了联合运算符:

defaults = dict(who="someone", where="somewhere")
params = dict(where="our town", when="today")
defaults | params
    {'who': 'someone', 'where': 'our town', 'when': 'today'}

注意,顺序很重要。在这种情况下,正如预期,来自 paramswhere 值覆盖了默认值。

删除前缀

如果你用 Python 做临时的文本解析或清理,你会写出这样的代码:

def process_pricing_line(line):
    if line.startswith("pricing:"):
        return line[len("pricing:"):]
    return line
process_pricing_line("pricing:20")
    '20'

这样的代码很容易出错。例如,如果字符串被错误地复制到下一行,价格就会变成 0 而不是 20,而且会悄悄地发生。

从 Python 3.9 开始,字符串有了一个 .lstrip() 方法:

"pricing:20".lstrip("pricing:")
    '20'

任意的装饰器表达式

以前,关于装饰器中允许哪些表达式的规则没有得到充分的说明,而且很难理解。例如:虽然

@item.thing
def foo():
    pass

是有效的,而且:

@item.thing()
def foo():
    pass

是有效的,相似地:

@item().thing
def foo():
    pass

产生一个语法错误。

从 Python 3.9 开始,任何表达式作为装饰器都是有效的:

from unittest import mock

item = mock.MagicMock()

@item().thing
def foo():
    pass
print(item.return_value.thing.call_args[0][0])
    <function foo at 0x7f3733897040>

虽然在装饰器中保持简单的表达式仍然是一个好主意,但现在是人类的决定,而不是 Python 分析器的选择。

欢迎来到 2020 年

Python 3.9 大约在一年前发布,但在这个版本中首次出现的一些特性非常酷,而且没有得到充分利用。如果你还没使用,那么将它们添加到你的工具箱中。


via: https://opensource.com/article/21/5/python-39-features

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索只接受位置参数和其他两个未被充分利用但仍然有用的 Python 特性。

 title=

这是 Python 3.x 首发特性系列文章的第九篇。Python 3.8 于 2019 年首次发布,两年后,它的许多很酷的新特性仍然没有被使用。下面是其中的三个。

importlib.metadata

入口点 在 Python 包中被用来做各种事情。大多数人熟悉的是 console\_scripts 入口点,不过 Python 中的许多插件系统都使用它们。

在 Python 3.8 之前,从 Python 中读取入口点的最好方法是使用 pkg_resources,这是一个有点笨重的模块,它是 setuptools 的一部分。

新的 importlib.metadata 是一个内置模块,它允许访问同样的东西:

from importlib import metadata as importlib_metadata

distribution = importlib_metadata.distribution("numpy")
distribution.entry_points
    [EntryPoint(name='f2py', value='numpy.f2py.f2py2e:main', group='console_scripts'),
     EntryPoint(name='f2py3', value='numpy.f2py.f2py2e:main', group='console_scripts'),
     EntryPoint(name='f2py3.9', value='numpy.f2py.f2py2e:main', group='console_scripts')]

入口点并不是 importlib.metadata 允许访问的唯一东西。可以调试、报告,或者(在极端情况下)触发兼容模式,你也可以在运行时检查依赖的版本!

f"{distribution.metadata['name']}=={distribution.version}"`[/code] [code]`    'numpy==1.20.1'

只接受位置参数

强制关键字的参数在传达 API 作者的意图方面取得巨大成功之后,另一个空白被填补了:只接受位置参数。

特别是对于那些允许使用任意关键字的函数(例如,生成数据结构),这意味着对允许的参数名称的限制更少:

def some_func(prefix, /, **kwargs):
    print(prefix, kwargs)
some_func("a_prefix", prefix="prefix keyword value")
   a_prefix {'prefix': 'prefix keyword value'}`

注意,令人困惑的是,变量 prefix 的值与 kwargs["prefix"] 的值不同。就像在很多地方一样,要注意小心使用这个功能。

自我调试表达式

50 多年来,print() 语句(及其在其他语言中的对应语句)一直是快速调试输出的最爱。

但是我们在打印语句方面取得了很大的进展,比如:

special_number = 5
print("special_number = %s" % special_number)
    special_number = 5

然而,自我记录的 f-strings 使它更容易明确:

print(f"{special_number=}")
    special_number=5`

在 f-string 插值部分的末尾添加一个 =,可以保留字面部分,同时添加数值。

当更复杂的表达式在该部分内时,这就更有用了:

values = {}
print(f"{values.get('something', 'default')=}")
    values.get('something', 'default')='default'

欢迎来到 2019 年

Python 3.8 大约在两年前发布,它的一些新特性非常酷,而且没有得到充分利用。如果你还没使用,那么将他们添加到你的工具箱中。


via: https://opensource.com/article/21/5/python-38-features

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解更多关于这个和其他两个未被充分利用但仍然有用的 Python 特性。

 title=

这是关于 Python 3.x 首发特性系列文章的第八篇。Python 3.7 于 2018 年首次发布,尽管它已经发布了几年,但它引入的许多特性都未被充分利用,而且相当酷。下面是其中的三个。

注解推迟评估

在 Python 3.7 中,只要激活了正确的 __future__ 标志,注解在运行时就不会被评估:

from __future__ import annotations

def another_brick(wall: List[Brick], brick: Brick) -> Education:
    pass
another_brick.__annotations__
    {'wall': 'List[Brick]', 'brick': 'Brick', 'return': 'Education'}

它使递归类型(指向自己的类)和其他有趣的事情成为了可能。然而,这意味着如果你想做自己的类型分析,你需要明确地使用 ast

import ast
raw_type = another_brick.__annotations__['wall']
[parsed_type] = ast.parse(raw_type).body
subscript = parsed_type.value
f"{subscript.value.id}[{subscript.slice.id}]"
    'List[Brick]'

itertools.islice 支持 index

Python 中的序列切片长期以来一直接受各种 类 int 对象(具有 __index__() 的对象)作为有效的切片部分。然而,直到 Python 3.7,itertools.islice,即核心 Python 中对无限生成器进行切片的唯一方法,才获得了这种支持。

例如,现在可以用 numpy.short 大小的整数来切片无限生成器:

import numpy
short_1 = numpy.short(1)
short_3 = numpy.short(3)
short_1, type(short_1)
    (1, numpy.int16)
import itertools
list(itertools.islice(itertools.count(), short_1, short_3))
    [1, 2]

functools.singledispatch() 注解注册

如果你认为 singledispatch 已经很酷了,你错了。现在可以根据注解来注册了:

import attr
import math
from functools import singledispatch

@attr.s(auto_attribs=True, frozen=True)
class Circle:
    radius: float
       
@attr.s(auto_attribs=True, frozen=True)
class Square:
    side: float

@singledispatch
def get_area(shape):
    raise NotImplementedError("cannot calculate area for unknown shape",
                              shape)

@get_area.register
def _get_area_square(shape: Square):
    return shape.side ** 2

@get_area.register
def _get_area_circle(shape: Circle):
    return math.pi * (shape.radius ** 2)

get_area(Circle(1)), get_area(Square(1))
    (3.141592653589793, 1)

欢迎来到 2017 年

Python 3.7 大约是四年前发布的,但是在这个版本中首次出现的一些特性非常酷,而且没有得到充分利用。如果你还没使用,那么将它们添加到你的工具箱中。


via: https://opensource.com/article/21/5/python-37-features

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索 os.fspath 和其他两个未被充分利用但仍然有用的 Python 特性。

 title=

这是 Python 3.x 首发特性系列文章中的第七篇。Python 3.6 首次发布于 2016 年,尽管它已经发布了一段时间,但它引入的许多特性都没有得到充分利用,而且相当酷。下面是其中的三个。

分隔数字常数

快回答哪个更大,10000000 还是 200000?你在看代码时能正确回答吗?根据当地的习惯,在写作中,你会用 10,000,000 或 10.000.000 来表示第一个数字。问题是,Python 使用逗号和句号是用于其他地方。

幸运的是,从 Python 3.6 开始,你可以使用下划线来分隔数字。这在代码中和使用字符串的 int() 转换器时都可以使用:

import math
math.log(10_000_000) / math.log(10)
    7.0
math.log(int("10_000_000")) / math.log(10)
    7.0

Tau 是对的

45 度角用弧度表示是多少?一个正确的答案是 π/4,但这有点难记。记住 45 度角是一个八分之一的转角要容易得多。正如 Tau Manifesto 所解释的,,称为 Τ,是一个更自然的常数。

在 Python 3.6 及以后的版本中,你的数学代码可以使用更直观的常数:

print("Tan of an eighth turn should be 1, got", round(math.tan(math.tau/8), 2))
print("Cos of an sixth turn should be 1/2, got", round(math.cos(math.tau/6), 2))
print("Sin of a quarter turn should be 1, go", round(math.sin(math.tau/4), 2))
    Tan of an eighth turn should be 1, got 1.0
    Cos of an sixth turn should be 1/2, got 0.5
    Sin of a quarter turn should be 1, go 1.0

os.fspath

从 Python 3.6 开始,有一个神奇的方法表示“转换为文件系统路径”。当给定一个 strbytes 时,它返回输入。

对于所有类型的对象,它寻找 __fspath__ 方法并调用它。这允许传递的对象是“带有元数据的文件名”。

open()stat 这样的普通函数仍然能够使用它们,只要 __fspath__ 返回正确的东西。

例如,这里有一个函数将一些数据写入一个文件,然后检查其大小。它还将文件名记录到标准输出,以便追踪:

def write_and_test(filename):
    print("writing into", filename)
    with open(filename, "w") as fpout:
        fpout.write("hello")
    print("size of", filename, "is", os.path.getsize(filename))

你可以用你期望的方式来调用它,用一个字符串作为文件名:

write_and_test("plain.txt")
    writing into plain.txt
    size of plain.txt is 5

然而,可以定义一个新的类,为文件名的字符串表示法添加信息。这样可以使日志记录更加详细,而不改变原来的功能:

class DocumentedFileName:
    def __init__(self, fname, why):
        self.fname = fname
        self.why = why
    def __fspath__(self):
        return self.fname
    def __repr__(self):
        return f"DocumentedFileName(fname={self.fname!r}, why={self.why!r})"

DocumentedFileName 实例作为输入运行该函数,允许 openos.getsize 函数继续工作,同时增强日志:

write_and_test(DocumentedFileName("documented.txt", "because it's fun"))
    writing into DocumentedFileName(fname='documented.txt', why="because it's fun")
    size of DocumentedFileName(fname='documented.txt', why="because it's fun") is 5

欢迎来到 2016 年

Python 3.6 是在五年前发布的,但是在这个版本中首次出现的一些特性非常酷,而且没有得到充分利用。如果你还没使用,那么将他们添加到你的工具箱中。


via: https://opensource.com/article/21/5/python-36-features

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出