Lua-简洁、轻量、可扩展的脚本语言
转自:http://rmingwang.com/The-Programming-Language-Lua.html
1. 一、Lua安装及常用库的安装
2. 1.1 Ubuntu
$ sudo apt-get install lua5.2
3. 1.2 OS X
$ brew install lua luarocks # luarocks是lua的模块管理工具$ sudo ln -s /usr/bin/make /usr/bin/gmake # 解决 sh: gmake: command not found
4. 1.3 luasocket库的安装
$ luarocks install luasocket$ lua> socket = require("socket")> print(socket._VERSION)LuaSocket 2.0.2
5. 1.4 lua-cjson库的安装
$ luarocks install lua-cjson$ lua> cjson = require("cjson")> print(cjson.encode({ name = "linguofeng" })){"name":"linguofeng"}
6. 二、HelloWorld
$ lua> print("Hello World!!")Hello World!!
7. 三、数据类型 有8种基本数据类型
类型 说明nil 全局变量默认值,如果要删除一个全局变量可以赋值为nilboolean 布尔值number 数字型string 字符串型userdata 用户自定义类型,一般是C/C++中的类型function 函数thread 线程table 表print(type(nil)) -- 输出 nilprint(type(99.7+12*9)) -- 输出 numberprint(type(true)) -- 输出 booleanprint(type("Hello Wikipedia")) -- 输出 stringprint(type(print)) -- 输出 functionprint(type{1, 2, test = "test"}) -- 输出 table
8. 四、函数 第一类值
第一类值指:在Lua中函数和其他值(数值、字符串)一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。
function add(x, y) -- 定义一个函数add,并接收两个参数local a = x + y -- 定义一个局部变量a,接收x+y的和,局部变量仅在函数add中有效return a -- 返回end -- 结束add函数print("15 + 64 = " .. add(15, 64)); -- 打印add(15, 64)的结果local x = 1 -- local 关键字表示该变量为局部变量,作用域为当前上下文-- 无该关键字修饰时为全局变量,作用于整个Lua状态机local add = function(x, y) -- 局部函数,作用于当前脚本(chumk)Lib = {}Lib.add = function(x, y) -- 表函数,作用于Lib表
9. 函数闭包
闭包是一个内部函数以及它的upvalues,内部函数使用了外部(父函数)局部变量。
function newCounter()local i = 0 -- i为匿名函数的外部局部变量(upvalue)return function() -- 匿名内部函数i = i + 1 -- 使用了i,所以该匿名函数是一个闭包return iendendc1 = newCounter() -- 得到一个匿名函数的变量(闭包)print(c1()) -- 调用匿名函数,打印出1print(c1()) -- 调用匿名函数,打印出2c2 = newCounter()print(c2()) --> 1print(c1()) --> 3print(c2()) --> 2
10. 五、控制语句
for int i = 0, 10, 2 do -- for循环,2表示步长,省略时为1print("i = " .. i) -- .. 表示字符串连接符end -- 结束forif a > b then -- if条件判断语句print("a > b")elseprint("b > a")endwhile a > b do -- while循环print("")endrepeat -- repeat-until循环print("")until a > b
11. 六、逻辑运算符 and、or、not
逻辑运算符认为false和nil是假(false),其他为真,0也是true.
a and b -- 如果a为false,则返回a,否则返回ba or b -- 如果a为true,则返回a,否则返回bx = x or v -- 如果x为false或者nil时则给x赋初始值v-- 等价于if not x thenx = vend-- 三元运算符a ? b : c => a and b or c -- and 的优先级别比 or 高not -- not 的结果只返回false或true,作用类似于"非" "!"取反的意思print(not nil) -- trueprint(not false) -- trueprint(not 0) -- false
12. 七、协同程序 coroutine
7.1 创建协同
co = coroutine.create(function () -- 创建一个协同函数,接收一个匿名函数,返回thread类型print("hi")end)print(co) -- thread: 0x7fe1834127d0
7.2 协同的三个状态:挂起态(suspended)、运行态(running)、停止态(dead)。
print(coroutine.status(co)) -- 查看协同的状态,默认状态是挂起态 suspendedcoroutine.resume(co) -- 改变协同的状态为运行太 hiprint(coroutine.status(co)) -- 协同运行完以后将变量停止态 dead
7.3 如此挂起正在运行的协同
co = coroutine.create(function ()print("hi")coroutine.yield() -- 协同运行到此状态将变成挂起print("你好")end)coroutine.resume(co) -- hicoroutine.resume(co) -- 你好coroutine.resume(co) -- false,协同结束后将不能再使用
7.4 协同数据交换
co = coroutine.create(function (x, y) -- 接收两个参数print("hi", coroutine.yield(x + y)) -- 返回一个值,同时参数也传递给了coroutine.yieldreturn 100 -- 第三种返回值的方式end)print(coroutine.resume(co, 12, 87)) -- 传递两个参数并接收返回值(true, 99)-- 执行coroutine.yield(x + y)之前协同被挂起,但值被返回,因此print函数未被执行,下面执行print(coroutine.resume(co, 12, 87)) -- 传递两个参数并接收返回值(true, 100)
13. 八、数据结构 table
8.1 表的创建
arrays = {} -- 创建一个空表arrays[1] = "abc" -- 第一个索引值为1arrays[2] = 123arrays["key"] = "value" -- mapfor key, value in pairs(arrays) do -- 迭代tableprint(key .. " = " .. value)end
8.2 表的增删改查
list = {123} -- 初始化表list[2] = "abc" -- 增list.x = 123list.y = 987list[1] = nil -- 删list.y = nillist[2] = 456 -- 改list.x = 987print(list[2]) -- 查print(list.x)print(list['x'])
8.3 数组
list = {} -- 初始空化数组,数组的下标是整数,遵循Lua的标准,下标从1开始list[1] = "abc"list[2] = "edg"list[3] = "hij"
8.4 矩阵(二维数组)
mt = {} -- 创建矩阵matrixfor i = 1, N do -- 创建N行mt[i] = {} -- 每行都是一个数组(table元素)for j = 1, M do -- 创建M列mt[i][j] = "a" -- 第N行第M行的值endend
8.5 链表
Singly-linked-list.svglist = nillist = {next = list, value = "hello3"}list = {next = list, value = "hello2"}list = {next = list, value = "hello1"}-- 遍历local l = listwhile l doprint(l.value)l = l.nextend
14. 九、metatable 元表
9.1 元表与元方法
元表也是普通表
t = {}print(getmetatable(t)) -- 获取表的metatable nil,默认不带mt = {}setmetatable(t, mt) -- 设置一个元素-- metamethod 元表的方法(元方法)mt.__add -- 加 +mt.__sub -- 减 -mt.__mul -- 乘 *mt.__div -- 除 /mt.__unm -- 负 -mt.__pow -- 幂 ^mt.__concat -- 连接mt.__eq -- 等于 =mt.__lt -- 小于 <mt.__le -- 大于 >mt.__tostring -- print调用mt.__metatable -- 设置该元表不被修改与访问mt.__index -- 当访问不存在的元素时会去查询,相当于子类继承父类一样mt.__newindex -- 更新表,如果增加一个不存在的元素,会去查询,有直接用,否则增加
9.2 表的代理
记录下表的增查记录
local index = {} -- 私有的key,用来记录原始表在代理表中的下标local mt = { -- 创建元表__index = function(t, k)print("访问了" .. tostring(k) .. "元素")return t[index][k] -- 从代理表中获取原始表中k下标的数据end,__newindex = function(t, k, v)print("更新了 " .. tostring(k) .. " 元素的值为 " .. tostring(v))t[index][k] = v -- 更新代理表中下标为index的原始表中的元素end}function setProxy(t)local proxy = {} -- 创建代理表proxy[index] = t -- 把原始表加到代理表的index下标中setmetatable(proxy, mt) -- 设置代理表的元表return proxy -- 返回代理表,即所有操作都是直接操作代理表endp = setProxy({})p[2] = 'abcdefg' -- 更新了 2 元素的值为 abcdefgprint(p[2]) -- 访问了2元素
15. 十、环境
10.1 全局变量 _G
> _G["ewgegw"] = "ddddddgege"> table.foreach(_G, print)string table: 0x7ffce3407a60xpcall function: 0x7ffce3404780package table: 0x7ffce3405780tostring function: 0x7ffce3405020print function: 0x7ffce3405160os table: 0x7ffce34073e0unpack function: 0x7ffce34050d0ewgegw ddddddgege -- 上面添加的全局变量require function: 0x7ffce3405e70getfenv function: 0x7ffce3404db0setmetatable function: 0x7ffce3404f60next function: 0x7ffce3404d20assert function: 0x7ffce3404a80tonumber function: 0x7ffce3404fc0io table: 0x7ffce3406bd0rawequal function: 0x7ffce34051b0collectgarbage function: 0x7ffce3404ad0getmetatable function: 0x7ffce3404e00module function: 0x7ffce3405e20rawset function: 0x7ffce3405260math table: 0x7ffce3408290debug table: 0x7ffce3408c50pcall function: 0x7ffce3404d70table table: 0x7ffce3405f10newproxy function: 0x7ffce34052e0type function: 0x7ffce3405080coroutine table: 0x7ffce3405380 -- 对应的是协同的表_G table: 0x7ffce3404110select function: 0x7ffce3404ec0gcinfo function: 0x7ffce3404150pairs function: 0x7ffce34048c0rawget function: 0x7ffce3405210loadstring function: 0x7ffce3404cc0ipairs function: 0x7ffce3404830_VERSION Lua 5.1dofile function: 0x7ffce3404bd0setfenv function: 0x7ffce3404f10load function: 0x7ffce3404c70error function: 0x7ffce3404c20loadfile function: 0x7ffce3404e60> table.foreach(_G.os, print)
10.2 非全局变量 setfenv
--pack.lua---------------------------------------------------------------------local P = {}-- 改变P表的__index,这里的_G代表全局环境setmetatable(P, {__index = _G})-- 改变当前的环境为P,setfenv前的所有定义都是在全局环境中进行的,后面的则都是在新环境中进行的,互不影响setfenv(1, P)-- 声明的add函数在环境P中,如果要在外部访问必须P.addfunction add(x, y)print(x .. ' + ' .. y .. ' = ' .. (x + y))-- 由于当前新的环境中没有print函数,但是__index指向的是全局环境,所以print是全局的函数endreturn P--pack1.lua--------------------------------------------------------------------local P = {}-- 如果需要改变环境后使用全局环境的方法需要记住,这种方法比上面的要快local print = print-- 改变当前的环境为Psetfenv(1, P)-- 声明的add函数在环境P中,如果要在外部访问必须P.addfunction add(x, y)print(x .. ' + ' .. y .. ' = ' .. (x + y))end-- 私有方法local function div(x, y)endreturn P--main.lua---------------------------------------------------------------------local p = require 'pack'p.add(12, 34)local p1 = require 'pack1'p1.add(43, 19)
16. 十一、包 package
11.1 包的定义
-- student.luastudent = {}function student.sayHi()print('Hello')endreturn student-- 使用student = require("student")student.sayHi() -- Hello11.2 私有函数local function _add(x, y) -- 私有局部函数return x + yendutils = { -- utils包add = _add -- 对外公开的函数}return utils
17. 十二、面向对象
12.1 类与继承
--Person.lualocal Person = {name = ''}function Person:getName()return self.nameendfunction Person:setName(name)self.name = nameendfunction Person:new(object)object = object or {}setmetatable(object, {__index = self}) -- 元表 类似继承的意思return objectendreturn Person--main.lua-- 类local Person = require 'Person'-- 对象local student = Person:new({age = 23})student:setName('Tom')print('name: ' .. student:getName() .. ' age: ' .. student.age)
12.2 多重继承
实际就是记住所有父类,然后访问不存在的元素的时候去查询哪个父类中有,有就执行
local function search (k, plist)for i=1, table.getn(plist) dolocal v = plist[i][k] -- 去所有父类中获取if v then return v endendendfunction Person:new(...)local o = {}setmetatable(o, {__index = function (t, k)local v = search(k, arg)t[k] = v -- save for next accessreturn vend})return oend
12.3 私有性
local function createAccount(_name) -- 工厂方法local self = {name = _name}local function _setName(name)self.name = nameendlocal function _getName()return self.nameend-- 公有方法表local public = {setName = _setName,getName = _getName,--name = self.name -- 不公开私有成员变量}return publicendlocal account = createAccount('Tom')print(account.name) -- 无法访问,因为没有公开
18. 十三、weak table
t = {name = 'table'} -- 创建一个普通表setmatetable(t, {__made = 'k'}) -- k表示t表中的keys是weak的,v表示t表中的values是weak的k = {} -- 创建一个空表,此时{}被k引用,引用值为1t[k] = 1 -- 把空表作为key,由于t表的key是weak的,所以k值的引用如果为0则会被gc回收,如k = {} -- 把k指向另一个新的{},则旧的{}引用值减1变成0了,目前t[k] = 1还有效t[k] = 2 -- 把新的{}作为key,值是2collectgarbage() -- 调用gc,清除引用为0的内存空间,此时,第一个{}的引用是0,会被gc掉,所以第一个t[k]以及值会被删除for k, v in pairs(a) do print(v) end-- 此时应该只剩下2了,因为第2个k = {}时改变了k指向新的{},而旧的{}引用会变成0,被gc掉-------------------------------------------------------------------------a = {};setmetatable(a, {__mode = 'v'}); -- values为weak,当值的引用为0时,删除v1 = {name = 'v1'}v2 = {name = 'v2'}a[1] = v1a[2] = v2v1 = v2collectgarbage(); -- 调用GC,清掉weak表中没有引用的内存for k, v in pairs(a) do print(v.name) end-- 输出v2,因为v1重新指向{name = 'v2'},则{name = 'v1'}引用减1为0-------------------------------------------------------------------------a = {};setmetatable(a, {__mode = 'kv'}); -- 同时检查kv,是上面两种情况的组合v1 = {name = 'v1'}v2 = {name = 'v2'}v = {}k = {}a[1] = vv = {} -- value重新引用新值,旧值被gc,如果旧值在table则对应的记录被清空a[2] = va[k] = 1k = {} -- key重新引用新值,旧值被gc,如果旧值在table则对应的记录被清空a[k] = 2collectgarbage(); -- 调用GC,清掉weak表中没有引用的内存for k, v in pairs(a) doprint(v)end
19. 十四、标准库
19.1. 14.1 数学库 Mathematical Functions
函数 说明math.abs (x) 求绝对值math.acos (x) 求反余弦math.asin (x)math.atan (x)math.atan2 (y, x)math.ceil (x)math.cos (x)math.cosh (x)math.deg (x)math.exp (x)math.floor (x)
20. 14.2 table库
函数 说明table.concat (table [, sep [, i [, j]]]) 拼接成字符串,sep代表连接符,i开始位置,j结束位置table.insert (table, [pos,] value) 插入一个元素,默认是最后一个,pos指定位置table.maxn (table) 获取最大长度table.remove (table [, pos]) 删除一个元素,默认删除最后一个,pos指定位置table.sort (table [, comp]) 排序tables = {1, 2, 3, 4, 5, 6, 7}print(#tables) -- 5.1开始使用#获取长度 -- 7table.insert(tables, 8)print(table.concat(tables)) -- 12345678table.insert(tables, 1, 0)print(table.concat(tables)) -- 012345678print(table.maxn(tables)) -- 9table.remove(tables)print(table.concat(tables)) -- 01234567table.remove(tables, 5)print(table.concat(tables)) -- 0123567print(table.concat(tables, ',')) -- 0,1,2,3,5,6,7print(table.concat(tables, '-', 2)) -- 1-2-3-5-6-7print(table.concat(tables, '=', 1, 4)) -- 0=1=2=3table.sort(tables)print(table.concat(tables)) -- 0123567table.sort(tables, function(t1, t2)if t1 > t2 thenreturn trueelsereturn falseendend)print(table.concat(tables)) -- 7653210
21. 14.3 string库
函数 说明string.byte (s [, i [, j]]) 把字符转换成ASCII码string.char (…) 把ASCII码转换成字符string.dump (function)string.find (s, pattern [, init [, plain]]) 查找,pattern查找的字符串,init从那里开始默认为1,plainstring.format (formatstring, …) 格式化字符串
22. 14.4 io库
函数 说明io.close ([file]) 等效file:close(),如果没有file则关闭默认输出io.flush () 等效file:flush()io.input ([file])io.lines ([filename]) 等效io.input():lines()io.open (filename [, mode]) 打开一个文件,模式:r,w,a,r+,w+,a+io.output ([file])io.popen (prog [, mode]) 依赖系统的,不是所有平台都能用io.read (…) 等效io.input():readio.tmpfile () 创建一个临时文件,当程序退出时自动删除io.type (obj) 判断obj的类型,如果返回file是一个打开的文件句柄,返回close file是一个关闭的文件句柄,nil不是文件io.write (…) 等效io.output():writefile:close () 关闭文件,会自动gc掉,但时间不确定file:flush () 保存任何数据到文件中file:lines () 迭代文件的每一行file:read (…) 读取文件,*n,*a,*l,numberfile:seek ([whence] [, offset]) 指定位置,默认是cur,1,set,endfile:setvbuf (mode [, size]) 设置buff缓存,no,full,linefile:write (…) 写文件,参数必须是string或者numberlocal file = io.open('tabletest.lua', 'r')print(io.type(file))for line in file:lines() do--print(line)end--file:close()io.close(file)print(io.type(file))------------------------------------------------------for line in io.input('tabletest.lua'):lines() doprint(line)endfor line in io.lines('tabletest.lua') do--print(line)end
23. 14.5 os库
函数 说明os.clock () 返回程序所使用的cpu时间os.date ([format [, time]]) 当前系统日期,或格式化某个日期os.difftime (t2, t1) 时间差os.execute ([command]) 执行shell命令os.exit ([code]) 调用C的exit函数os.getenv (varname) 获取系统环境变量,变量名,不包含$os.remove (filename) 删除文件,文件名os.rename (oldname, newname) 修改文件名os.setlocale (locale [, category]) 设置地区,"all", “collate”, “ctype”, “monetary”, “numeric”, or “time”os.time ([table]) 返回当前时间或把时间保存在table中,os.tmpname () 临时文件名table.foreach(os, print)print(os.clock())print(os.date())print(os.date('%Y-%m-%d %H:%M'))print(os.time())print(os.difftime(1364957757, os.time()))print(os.getenv ('PATH'))print(os.tmpname ())
14.6 debug库
函数 说明
24. 十五、标准库
15.1 堆栈,后进先出原则
25. 压入
函数 说明(栈底最后一个元素的索引是1,栈顶第一个元素是-1)lua_pushnil(lua_State*) 压入一个空值lua_pushboolean(lua_State*, int) 压入一个布尔值lua_pushcclosure(lua_State*, lua_CFunction, int) 压入一个C闭包?lua_pushcfunction(lua_State*, lua_CFunction) 压入一个C函数,由lua_pushcclosure(L, f, 0)宏定义出来lua_pushlightuserdata(lua_State*, void*) 压入一个指针,不被gc管理lua_pushinteger(lua_State*, lua_Integer) 压入一个数字lua_pushnumber(lua_State*, lua_Number) 压入数字lua_pushstring(lua_State*, const char*) 压入字符串lua_pushfstring(lua_State*, const char*, …) 压入一个格式化的stringlua_pushvfstring(lua_State*, const char*, va_list) 同上,只是接收一个va_listlua_pushlstring(lua_State*, const char*, size_t); 压入长字符串lua_pushliteral(lua_State*, const char*) 压入文字lua_pushthread(lua_State*) 压入一个线程?
26. 判断类型
函数 说明lua_isboolean(lua_State*, int) 是否是布尔类型lua_iscfunction(lua_State*, int) 是否是C函数类型lua_isfunction(lua_State*, int) 是否是C函数或者Lua函数lua_islightuserdata(lua_State*, int) 是否是用户自定义类型指针lua_isnil(lua_State*, int) 是否是空lua_isnone(lua_State*, int) 是否是有效的lua_isnoneornil(lua_State*, int) 是否是上面两者lua_isnumber(lua_State*, int) 是否是数字lua_isstring(lua_State*, int) 是否是字符串lua_istable(lua_State*, int) 是否是tablelua_isthread(lua_State*, int) 是否是线程lua_isuserdata(lua_State*, int) 是否是用户类型,包括full和lightlua_type(lua_State*, int) 返回元素的类型,对应LUA_TNIL等枚举lua_typename(lua_State*, int) 返回元素的类型名称
27. 获取栈中的元素并转换成C类型
函数 说明 返回值类型lua_toboolean(lua_State*, int) 把元素转换成C的布尔类型的值 intlua_tocfunction(lua_State*, int) 把元素转换成C的函数 lua_CFunctionlua_tointeger (lua_State*, int) lua_Integerlua_tolstring (lua_State*, int, size_t *len) const char*lua_tonumber (lua_State*, int) lua_Numberlua_topointer (lua_State*, int) const void*lua_tostring (lua_State*, int) const char*lua_tothread (lua_State*, int) lua_Statelua_touserdata (lua_State*, int) void*栈内元素的操作函数 说明lua_gettop(lua_State*) 返回栈的元素个数,同时也是栈顶元素的索引lua_settop(lua_State*, int) 设置某个元素为栈顶元素,该元素之上的元素会被清除lua_pushvalue(lua_State*, int) 压入(拷贝)一个已经存在栈的元素至栈顶lua_insert(lua_State*, int) 移动栈顶元素至某个位置lua_remove(lua_State*, int) 删除栈中某个元素lua_replace(lua_State*, int) 替换栈顶元素至某个位置,相应那个位置的元素至栈顶
参考:http://www.lua.org/manual/5.1/manual.html
原文地址:http://blog.linguofeng.com/pages/language/lua.html
Lua-简洁、轻量、可扩展的脚本语言的更多相关文章
- 深入LUA脚本语言,让你彻底明白调试原理
这是道哥的第008篇原创 一.前言 上篇文章我们聊了gdb的底层调试机制,明白了gdb是利用操作系统提供的系统信号来调试目标程序的.很多朋友私下留言了,看到能帮助到大家,我心里还是很开心的,其实这也是 ...
- 推荐一款轻量小众却高效免费开源windows热键脚本语言Autohotkey
写在前面的话 Autohotkey是一款轻量小众但高效免费开源的windows热键脚本语言,游戏操纵.鼠标操作.键盘快捷重定义,快捷短语等等,只有你想不到,没有它做不到,神器中的神器呀,相见恨晚. 安 ...
- OWIN轻量型框架介绍
OWIN轻量型框架介绍 阅读目录 引言 框架的特色 如何启动 各项功能 静态路由的3种写法 伪静态路由的支持 处理Form表单提交的文件 流式处理Post请求的数据 多种请求类型自动识别 响应处理 请 ...
- Just 5分钟!使用k3s部署轻量Kubernetes集群快速教程
大小仅有40MB的k3s为想要节省开销进行开发和测试的企业提供了一个很好的选择.本文将用一种极为简洁的方式,教你在5分钟之内使用k3s部署轻量Kubernetes集群. Kubernetes已经改变了 ...
- 对标 Spring Boot & Cloud ,轻量框架 Solon 1.4.8 发布
Solon 是一个轻量的Java基础开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Job.Micro service.WebS ...
- 对标 Spring Boot & Cloud ,轻量框架 Solon 1.4.12 发布
Solon 是一个轻量的Java基础开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Job.Micro service.WebS ...
- Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器
最近在业余时间玩玩树莓派,刚开始的时候在树莓派里写一些基于wiringPi库的C语言程序来控制树莓派的GPIO引脚,从而控制LED发光二极管的闪烁,后来觉得,是不是可以使用HTML5+jQuery等流 ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案
简单,是因为只有一个类 轻量,是因为整个类代码只有300行 灵活,是因为扩展方式只需要继承重写某个方法即可 补充:修正无法处理可空值类型的bug 首先我将这个类称之为JsonBuilder,我希望它以 ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案(续)
本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...
随机推荐
- Python简单的制作图片验证码
-人人可以学Python--这里示范的验证码都是简单的,你也可以把字符扭曲 人人可以学Python.png Python第三方库无比强大,PIL 是python的一个d第三方图片处理模块,我们也可以使 ...
- python安装基础
. python安装 //先查看是否存在python的包,如果没有,那可以用yum或去python的官网安装 [root@localhost ~]# rpm -qa|grep python pytho ...
- C/C++——[01] 程序的基本框架
我们以HelloWorld这个简单程序为例,该程序在终端打印一行文本: Hello World! 代码如下: #include <stdio.h> int main(){ printf(& ...
- transition结合:after,:before实现动画
div代码 <div class='div'> hover </div> css代码 .div{ width:200px; height:100px; line-height: ...
- 深入解析当下大热的前后端分离组件django-rest_framework系列二
视图三部曲 一部曲 · 使用混合(mixins) 上一节的视图部分: from rest_framework.views import APIView from rest_framework.resp ...
- hdu 1495(BFS)
非常可乐 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 【转载】WebService到底是什么?
http://blog.csdn.net/wooshn/article/details/8069087/ 一.序言 大家或多或少都听过WebService(Web服务),有一段时间很多计算机期刊.书籍 ...
- Centos7安装和配置Jira7.3.6
(1)安装jdk 1.下载jdk 链接:https://pan.baidu.com/s/1umdV-Cmm1wi1RP5clIJXmg 密码:zevc 2.安装jdk rpm -ivh jdk-8u1 ...
- android studio偏好设置
1.主题设置,可以选择白色主题及黑色主题 2.代码字体大小 3.生成新的主题 主题命名 4.加入代码时,自动引用库 5.合作菜单生成菜码 6.命名空间设置 字段设置为大写,静态字段设置为小写 SDK设 ...
- 一:Ionic Framework初体验
因项目关系,需要开发一个平板使用的应用程序,刚开始以为需要使用Andriod,后来经理提供了一个解决方案,Ionic Framework https://ionicframework.com/ 第一步 ...