px普贤教程PuXian
普贤教程 › 基础教程

第一个程序

一个 PuXian 程序就是一个 .px 文件。写完就能跑,跑完就能编译——这中间没有构建系统、没有依赖清单、没有虚拟环境。

第一段代码

px
# hello.px
def greet(name):
    return "你好," + name

print(greet("普贤"))
sh
px run hello.px
text
你好,普贤

注意这里没有 def main():顶层语句也会按顺序执行。def main() 的意义是"入口函数",解释器和编译器都会在顶层语句执行完之后自动调用它。

main 是被自动调用的

px
def main():
    print("main 里的输出")

print("顶层的输出")
text
顶层的输出
main 里的输出
最常见的重复执行不要在文件末尾再写一行 main()。语言已经替你调用了,手动再调一次会跑两遍,而且往往很难发现——输出重复了两遍才知道。

注释

px
# 单行注释:井号到行尾
## 文档注释也以 ## 开头,习惯放在文件顶部或函数上方

def add(a, b):
    # 函数体里同样用 #
    return a + b

没有多行注释语法。需要屏蔽一段代码时,逐行加 #;px fmt 不会擅自改动注释内容。

从解释到编译

sh
px run hello.px        # 解释执行
px build hello.px      # 编译
./hello/build/hello    # 运行产物

px build 的产物落在 <源码目录>/build/<文件名>。file 与 ldd 可以确认它是静态链接的:

sh
file hello/build/hello
ldd  hello/build/hello
text
hello/build/hello: ELF 64-bit LSB executable, x86-64, statically linked, ...
        not a dynamic executable
为什么先 run 再 build解释执行是秒起的,改一行就能看到结果;编译要几秒到十几秒。开发期用 run,发布前用 build 跑一遍冒烟测试。

一个稍完整的例子

px
# stat.px —— 统计一段文本里的单词频次
def count_words(text):
    var freq = {}
    var words = split(text, " ")
    for w in words:
        var k = trim(w)
        if len(k) == 0:
            continue
        if freq.has(k):
            freq[k] = freq[k] + 1
        else:
            freq[k] = 1
    return freq

def main():
    var freq = count_words("the quick brown fox jumps over the lazy dog the end")
    var keys = sorted(freq.keys())
    for k in keys:
        print(k + " " + str(freq[k]))
text
brown 1
dog 1
end 1
fox 1
jumps 1
lazy 1
over 1
quick 1
the 3

这段代码用到了字典、列表、for in 遍历、has 判断、sorted 排序、str() 转换。后面每一章会把它们逐个讲清楚。

练习

  1. 把 count_words 改成不区分大小写(提示:to_lower)。
  2. 让它按出现次数从多到少排序输出。
  3. 用 px build 编译它,给朋友拷一份二进制,确认对方机器不需要装 PuXian。