1、安装sass
1.安装ruby
因为sass是用ruby语言写的,所以需要安装ruby环境
打开安装包去安装ruby,记住要勾选 下面选项来配置环境路径
Add Ruby executables to your PATH
安装完成之后继续下一步操作
2.安装sass
在cmd里通过gem安装sass
gem是ruby的包管理工具,类似于nodejs 的npm
gem install sass1这个时候如果不翻墙的话是会出问题的,因为:
由于国内网络原因(你懂的),导致 rubygems.org 存放在 Amazon S3 上面的资源文件间歇性连接失败。这时候我们可以通过gem sources命令来配置源,先移除默认的https://rubygems.org源,然后添加淘宝的源https://ruby.taobao.org/,然后查看下当前使用的源是哪个,如果是淘宝的,则表示可以输入sass安装命令gem install sass了
$ gem sources --remove https://rubygems.org/$ gem sources -a https://ruby.taobao.org/ 【如果你系统不支持https,请将淘宝源更换成:gem sources -a http://gems.ruby-china.org】
$ gem sources -l
*** CURRENT SOURCES ***
https://ruby.taobao.org
# 请确保只有 ruby.taobao.org
$ gem install sass1234567
安装好之后执行sass -v就可以看到sass的版本了
实在实在不行,就安装离线文件吧,但是失败率也很高
gem install ./…/sass-3.4.22.gem
2、编译sass文件的方式
1.命令行编译
可以通过cmd命令行执行sass方法来编译
例如:
sass scss/a.scss:css/a.css1sass 后面写要编译的sass文件的路径,‘:’后面写的是
要输出的目录及名字
需要注意的是:必须有这个文件夹才能在里面生成css
这样的话写一句执行一次编译一次有些太麻烦
可以开启一个watch来监听文件变化来进行编译
sass --watch scss:css1–watch表示要监听 :前后的两个都是文件夹,表示scss文件夹的文件改变就编译到css文件夹
2.其他方式编译
除了命令行工具其实还可以用考拉、gulp等工具进行编译,但是ruby和sass是必须要安装的
考拉的方式就不多做介绍了,大家i自己去看一下
gulp的话呢是需要gulp-sass的模块来编译,使用方式类似于gulp-less
这里是网址,点击查看
3、sass四种风格
sass编译的格式
sass编译输出的css有四种格式
nested 嵌套
compact 紧凑
expanded 扩展
compressed 压缩
这些样式会影响输出的css的格式
简单介绍一下:
css默认输出的嵌套
ul{font-size:15px
li{
list-style:none
}
}123456
—》
ul {font-size: 15px}
ul li {
list-style: none}1234
紧凑compact
在编译的时候需要执行
sass --watch scss:css --style compact1这个时候输出的代码就是
ul { font-size: 15px}ul li { list-style: nonepadding: 5px}12
compressed 压缩
在编译的时候需要执行
sass --watch scss:css --style compressed1—>
ul{font-size:15px}ul li{list-style:noneanimation:all 0.4s}1expanded 扩展
更像是平时写的css一样
在编译的时候需要执行
sass --watch scss:css --style expanded1—>
ul {font-size: 15px
}
ul li {
list-style: none
animation: all 0.3s
}1234567
compressed 压缩
更像是平时写的css一样
在编译的时候需要执行
sass --watch scss:css --style compressed1—>
.a{width:100pxheight:100pxborder:1px solid red}.a .b{background:red}14、sass与scss
sass的两个语法版本
sass一开始用的是一种缩进式的语法格式
采用这种格式文件的后缀名是.sass
在sass3.0版本后我们常用的是sassy css语法,扩展名是.scss,更接近与css语法
两个版本的区别
后缀名不同 .sass和.scss
语法不同,请看下面
新版:
/*新版本多行文本注释*/
//新版本
//单行文本注释
@import "base"
@mixin alert{
color:red
background:blue
}
.alert-warning{
@include alert
}
ul{
font-size:15px
li{
list-style:none
}
}123456789101112131415161718
老版本:
/*新版本多行文本注释
//新版本
单行文本注释
@import "base"
=alert
color:red
background:blue
.alert-warning
+alert
ul
font-size:15px
li
list-style:none1234567891011121314
5、变量、嵌套、混合、继承拓展
变量的意义
在sass里我们可以定义多个变量来存放颜色、边框等等的样式,这样就可以在下面想要使用样式的时候使用变量了
这样的优点就是便于维护,更改方便
变量的使用
可以通过$来定义变量,在变量名字中可以使用-和_来作为连接,并且-和_是可以互通的,就是用起来一模一样。
变量的值可以是字符串、数字、颜色等等,在变量里还可以使用其他变量,使用的时候直接写变量名就好了
例如
$primary-color:#ff6600$primary-border:1px solid $primary_color
div.box{
background:$primary-color
}
h1.page-header{
border:$primary-border
}12345678
—》
div.box {background: #ff6600
}
h1.page-header {
border: 1px solid #ff6600
}123456
嵌套的使用
合理的使用嵌套语法,可以使我们编写代码更为快捷
假设我们想写这样的css:
.nav {height: 100px
}
.nav ul {
margin: 0
}
.nav ul li {
float: left
list-style: none
padding: 5px
}1234567891011
在sass里我们可以这样写
.nav{height:100px
ul{
margin:0
li {
float:left
list-style:none
padding:5px
}
}
}1234567891011
大家会发现,写出来的代码父和子之间都有空格隔开,如果我们需要给a加上伪类的话我们这样写
.nav{height:100px
a{
color:#fff
:hover{
color:#ff6600
}
}
}123456789
在里面就会出现这样的情况
.nav a :hover {color: #ff6600
}123
我们发现在a和:hover之间有了空格,这样是不好的,所以我们需要在写的时候在:hover之前把a加上,这样就需要用到在之类里引用父类选择器的方式,我们可以用&符号代替父类
例如:
.nav{height:100px
a{
color:#fff
&:hover{
color:#ff6600
}
}
}123456789
这样就好了,下面来个完整的代码:
.nav{height:100px
ul{
margin:0
li{
float:left
list-style:none
padding:5px
}
a{
display:block
color:#000
&:hover{
color:#f60
background:red
}
}
}
&&-text{
font-size:15px
}
}12345678910111213141516171819202122
-----》
.nav {height: 100px
}
.nav ul {
margin: 0
}
.nav ul li {
float: left
list-style: none
padding: 5px
}
.nav ul a {
display: block
color: #000
}
.nav ul a:hover {
color: #f60
background: red
}
.nav .nav-text {
font-size: 15px
}12345678910111213141516171819202122
嵌套属性
我们可以把一些个复合属性的子属性来嵌套编写,加快编写速度,例如
body{font:{
family:Helvitica
size:15px
weight:bold
}
}
.nav{
border:1px solid red{
left:none
right:none
}
}
.page-next{
transition:{
property:all
delay:2s
}
}12345678910111213141516171819
-----》
body {font-family: Helvitica
font-size: 15px
font-weight: bold
}
.nav {
border: 1px solid red
border-left: none
border-right: none
}
.page-next {
transition-property: all
transition-delay: 2s
}1234567891011121314
mixin 混合
你可以把它想象成一个有名字的定义好的样式
每一个mixin都有自己的名字,类似于js里的函数定义方法如下
@mixin 名字(参数1,参数2...){...
}123
使用方法是在其他选择器css样式里通过@include引入,其实就相当于将mixin里的代码写入到这个选择器的css里,如下:
@mixin alert {color:#f60
background-color:#f60
a{
color:pink
}
&-a{
color:red
}
}
.alert-warning{
@include alert
}12345678910111213
-----》
.alert-warning {color: #f60
background-color: #f60
}
.alert-warning a {
color: pink
}
.alert-warning-a {
color: red
}12345678910
刚才是没有参数的mixin,mixin也可以拥有参数,需要注意的是:
形参的名字前要加$
传参的时候只写值的话要按顺序传
传参的时候不想按顺序的话需要加上形参名字
例如:
@mixin alert($color,$background) {color:$color
background-color:$background
a{
color:darken($color,10%)//把颜色加深百分之十
}
}
.alert-warning{
@include alert(red,blue)
}
.alert-info{
@include alert($background:red,$color:blue)
}12345678910111213
------》
.alert-warning {color: red
background-color: blue
}
.alert-warning a {
color: #cc0000
}
.alert-info {
color: blue
background-color: red
}
.alert-info a {
color: #0000cc
}1234567891011121314
继承拓展 extend
如果我们有一个选择器想要拥有另一个选择所有的东西,不管是样式还是子元素等等,可以使用@extend来继承
大家需要注意的是,++b继承a的时候,a的子元素设置了样式,也会给b的子元素设置样式++,达到完全一样的情况,例如:
.alert {padding:5px
}
.alert a {
font:{
weight:bold
size:15px
}
}
.alert-info {
@extend .alert
backgournd:skyblue
}12345678910111213
----》
.alert, .alert-info {padding: 5px
}
.alert a, .alert-info a {
font-weight: bold
font-size: 15px
}
.alert-info {
backgournd: skyblue
}12345678910
partials
在以前咱们编写css的时候,一个css引入另一个css需要使用@import,其实这是不好的,会多发一次http请求,影响咱们站点的响应速度。
在sass里,咱们可以把小的sass文件分出去,叫做partials,在某个sass里通过@import ‘partials名’去引入,注意路径哟,这样的话就可以把partials里的代码引到咱们大的sass里一起编译
需要注意的是 partials的文件名前要加_
_base.sass :
body{margin:0
padding:0
}1234
style.sass :
@import "base".alert {
padding:5px
}
.alert a {
font:{
weight:bold
size:15px
}
}
.alert-info {
@extend .alert
backgournd:skyblue
}1234567891011121314
----------->
body {margin: 0
padding: 0
}
.alert, .alert-info {
padding: 5px
}
.alert a, .alert-info a {
font-weight: bold
font-size: 15px
}
.alert-info {
backgournd: skyblue
}1234567891011121314
这样的话我们就可以把模块化的思想引入到sass里了
comment注释
sass里的注释有三种
多行注释
单行注释
强制注释
多行注释:压缩后不会出现在css里 /* /
单行注释: 不会出现在css里 //
强制注释:压缩后也会出现在css里 /! */
6、数据类型与函数
数据类型
在sass里有数字、字符串、列表、颜色等类型
在cmd里 输入
sass -i1就会进入到交互模式,输入的计算可以马上得到结果
type-of()可以用来得到数据类型,如:
type-of(5) ->number1注意数字类型的可以包含单位,如:
type-of(5px) ->number1字符串类型:
type-of(hello) ->stringtype-of('hello') ->string12
list类型:
type-of(1px solid red) ->listtype-of(5px 10px) ->list12
颜色:
type-of(red) ->colortype-of(rgb(255,0,0) ->color
type-of(#333) ->color123
number 计算
2+9 -》102*8 -》16
(8/2) ->4 //除法要写括号123
也可以包含单位
5px + 5px ->10px5px -2 ->3px
5px *2 ->10px
5px * 2px ->10px*px //这样就不对了哟
(10px/2px) ->5//除法单位取消
3+2*5px->13px123456
好吧,都是一些小学的数学题,很简单对吧
处理数字的函数
绝对值
abs(10) ->10abs(10px) ->10px
abs(-10px) ->10px123
四舍五入相关
round(3.4)->3 //四舍五入round(3.6)->4
ceil(3.2)->4 //向上取整
ceil(3.6)->4
floor(3.2)->3 //向下取整
floor(3.9)->3
percentage(600px/1000px) ->65% //百分之
min(1,2,3) ->1 //最小值
max(2,3,4,5) ->5 //最大值123456789
字符串相关
//带引号和不带引号的字符串想加为带引号的字符串"a" + b ->"ab"
a + "b" ->"ab"
//字符串+数字
"ab" + 1 ->"ab1"
//字符串 - 和 / 字符串
"a" - b ->"a-b"
"a" / b ->"a/b"
//注意字符串不能相乘123456789
字符串函数
大写:
$word:"hello"to-upper-case($word) ->"HELLO"12
小写:
$word:"Hello"to-lower-case($word) ->"hello"12
得到length:
$word:"Hello"str-length($word) ->512
得到字符串在字符串里的位置:
$word:"Hello"str-index($word,"el") ->212
字符串中插入字符串:
$word:"Hello"str-insert($word,"aa",2) ->"Haaello"12
颜色相关
在sass里除了关键字、十六进制、rgb和rgba之外还有一种颜色是HSL
分别表示的是 色相 0-360(deg) 饱和度 0-100% 明度 0-100%
例如:
body {background-color:hsl(0,100%,50%)
}
-》
body {
background-color: red
}1234567
body {
background-color:hsl(60,100%,50%)
}
-》
body {
background-color: yellow
}1234567
也可以有透明哟
body {background-color:hsl(60,100%,50%,0.5)
}
-》
body {
background-color: rgba(255,255,0,0.5)
}1234567
颜色函数
lighten函数和darken函数可以把颜色加深或减淡,即调整明度,第一个参数为颜色,第二个参数为百分比,例如:
$color:#ff0000$light-color:lighten($color,30%)
$dark-color:darken($color,30%)
.a{
color:$color
background:$light-color
border-color:$dark-color
}12345678
—》
.a {color: #ff0000
background: #ff9999
border-color: #660000
}12345
saturate和desaturate函数可以调整颜色的纯度
$color:hsl(0,50%,50%)$saturate-color:saturate($color,50%)
$desaturate-color:desaturate($color,30%)
.a{
color:$color
background:$saturate-color
border-color:$desaturate-color
}12345678
–》
.a {color: #bf4040
background: red
border-color: #996666
}12345
用transparentize来让颜色更透明
用opatify来让颜色更不透明
$color:rgba(255,0,0,0.5)$opacify-color:opacify($color,0.3)
$transparentize-color:transparentize($color,0.3)
.a{
color:$color
background:$opacify-color
border-color:$transparentize-color
}12345678
—》
.a {color: rgba(255, 0, 0, 0.5)
background: rgba(255, 0, 0, 0.8)
border-color: rgba(255, 0, 0, 0.2)
}12345
列表类型
在sass里,用空格或者逗号隔开的值就是列表类型
如:
1px solid redCourier,microsoft yahei12
列表函数
sass里的列表类似与数组
获取列表的长度length(5px 10x) 2
获取列表中的第几个元素
nth(5px 10px,2) 10px
获取一个元素在一个列表里的下标
index(1px solid red,solid) 2
给列表里加入新的元素
append(5px 10px,5px) 5px 10px 5px
连接两个列表
join(5px 10px,5px 0) 5px 10px 5px 012345678910
map类型
sass里的map类型类似与js里的object
$map:(key1:value1,key2:value2,key3:value3)1map 函数
//定义一个map$color:(light:#ffffff,dark:#000000)
//获取map 的length
length($color) ->2
//得到map里key对应的值
map-get($color,dark) ->#000000
获取map里的所有键的列表
map-keys($color) ->("light","dark") //列表类型
获取map里的所有值的列表
map-values($color) ->("#ffffff","#000000") //列表类型
判断map里是否含有这个key
map-has-key($color,light) ->true
给map里添加键值对
map-merge($color,(light-gray:#cccccc))
->(light:#ffffff,dark:#000000,light-gray:#cccccc)
移除map里的某个键值对
map-remove($colors,light) ->(dark:#000000,light-gray:#cccccc)1234567891011121314151617
boolean类型
在sass里通过><比较得到的值就是布尔值 true 和false
5px>3px ->true5px<2px ->false12
在sass里也可以有或 且 非
且:
(5px >3px) and (5px <2px) ->false(5px >3px) and (5px >2px) ->true12
或:
(5px >3px) or (5px <2px) ->true(5px <3px) and (5px >2px) ->false12
非:
not(5px>3px) ->false1interpolation
在sass里可以通过interpolation的方式来在变量名和属性名上拼接变量值,例如
$name:"info"$attr:"border"
.alert-#{$name}{
#{$attr}-color:red
}12345
---->
.alert-info {border-color: red
}123
7、分支结构、循环结构、函数
分支结构
在sass里,可以使用@if让我们根据一些条件来应用特定的样式
结构:
@if 条件 {
}123
如果条件为真的话,括号里的代码就会释放出来
例如:
$use-refixes:true.rounded{
@if $use-refixes {
-webkit-border-radius:5px
-moz-border-radius:5px
-ms-border-radius:5px
-o-border-radius:5px
}
border-radius:5px
}12345678910
—>
.rounded {-webkit-border-radius: 5px
-moz-border-radius: 5px
-ms-border-radius: 5px
-o-border-radius: 5px
border-radius: 5px
}1234567
如果是另外一种情况
$use-refixes:false1—》
.rounded {border-radius: 5px
}123
if else在sass里的写法是:
body{@if $theme == dark {
background:black
} @else if $theme == light {
background:white
} @else {
background:gray
}
}123456789
for循环
在sass里的for循环是这样的
@for $var form <开始值>through <结束值>{...
}123
还有一种是
@for $var form <开始值>to <结束值>{...
}123
注意,开始值和结束值的关系可以是升序也可以是倒序,但是每次只能+1或者-1
这两种有什么区别呢?
区别就是 from 1 to 4 的话是执行三次,i的变化是 1 2 3
from 1 through 4 的话是执行四次,i的变化是 1 2 3 4
如:
from to
$columns:4@for $i from 1 to $columns{
.col-#{$i}{
width:100% / $columns * $i
}
}123456
—》
.col-1 {width: 25%
}
.col-2 {
width: 50%
}
.col-3 {
width: 75%
}123456789
from through
$columns:4@for $i from 1 through $columns{
.col-#{$i}{
width:100% / $columns * $i
}
}123456
—>
.col-1 {width: 25%
}
.col-2 {
width: 50%
}
.col-3 {
width: 75%
}
.col-4 {
width: 100%
}123456789101112
each 遍历list类型
在sass里可以利用each方法来遍历咱们的list类型的数据
list类型在js里类似于数组,那么each类似于for in遍历,结构如下:
@each $item in $list{...
}123
例如:
$colors:success error warning$map:(success:green,warning:yellow,error:red)
@each $color in $colors{
.bg-#{$color}{
background:map-get($map,$color)
}
}1234567
—>
.bg-success {background: green
}
.bg-error {
background: red
}
.bg-warning {
background: yellow
}123456789
@while 循环
在sass里,拥有@while循环,比@for会更好用一些,@for循环只能从一个数到另一个数变化之间执行,每次变化都是1,while设置循环结构的话更为灵活;
结构:
@while 条件{
}123
eq:
$i:6@while $i>0{
.item-#{$i}{
width:$i*5px
}
$i:$i - 2
}1234567
注意:$i - 2 需要用空格隔开哟
---------》
.item-6 {width: 30px
}
.item-4 {
width: 20px
}
.item-2 {
width: 10px
}123456789
自定义函数
在sass里也可以定义函数,并且也可以有返回值
结构:
@function 名称 (参数1,参数2){@return ...
}123
例如,我们做一个返回map里key对应的值的函数:
$colors:(light:#ffffff,dark:#000000,gray:#555555)@function color($key){
@return map-get($colors,$key)
}
body{
background:color(light)
color:color(dark)
border-color:color(gray)
}123456789
—》
body {background: #ffffff
color: #000000
border-color: #555555
}
1\模块如果退出Python解释程序然后再进入,原有的定义(函数和变量)就丢失了。所以,如
果需要写长一点的程序,最好用一个文本编辑程序为解释程序准备输入,然后以程序文
件作为输入来运行Python解释程序,这称为准备脚本(script)。当你的程序变长时,
最好把它拆分成几个文件以利于维护。你还可能想在几个程序中都使用某个很方便的函
数,但又不想把函数定义赋值到每一个程序中。
为了支持这些,Python有一种办法可以把定义放在一个文件中然后就可以在一个脚本中
或交互运行中调用。这样的文件叫做一个模块;模块中的定义可以导入其它模块或主模
块(主模块指在解释程序顶级执行的脚本或交互执行的程序所能访问的变量集合)。
模块是包含了Python定义和语句的文件。文件名由模块名加上后缀“.py”构成。在模块
内,模块的名字(作为一个字符串)可以由全局变量__name__的值获知。例如,在Pyth
on的搜索路径中用你习惯使用的文本编辑器(Python 1.5.2包含了一个用Tkinter编写的
IDLE集成开发环境,MS Windows下有一个PythonWin界面也可以进行Python程序编辑)生
成一个名为“fibo.py ”的文件,包含如下内容:
# Fibonacci numbers module
def fib(n):# 输出小于n的Fibonacci序列
a, b = 0, 1
while b <n:
print b,
a, b = b, a+b
def fib2(n): # 返回小于n的Fibonacci序列
result = []
a, b = 0, 1
while b <n:
result.append(b)
a, b = b, a+b
return result
然后进入Python解释程序(在IDLE或PythonWin中可以直接进入解释程序窗口),用如下
命令可以导入模块:
>>>import fibo
这不会把模块fibo中的函数的名字直接引入当前的符号表,这只是把模块名fibo引入。
可以用模块名来访问其中的函数:
>>>fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>>fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>>fibo.__name__
'fibo'
如果经常使用某个函数可以给它赋一个局部名字:
>>>fib = fibo.fib
>>>fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
6.1 模块的进一步介绍
模块除了可以包含函数定义之外也可以包含可执行语句。这些可执行语句用来初始化模
块,它们只在模块第一次被导入时执行。
每个模块有自己私有的符号表,这个私有符号表对于模块中的所有函数而言却是它们的
全局符号表。因此,模块作者可以在模块中使用全局变量而不需担心与模块用户的全局
变量冲突。另一方面,如果你有把握的话也可以用访问模块中函数的格式,即modname.
itemname的方法来修改模块中的全局变量。
模块可以导入其它模块。我们通常把所有的导入语句放在模块(或脚本)的开始位置,
这不是规定要求的。导入的模块名放入模块的全局符号表中。
导入还有另一种用法,可以把模块中的名字直接导入使用者的符号表。例如:
>>>from fibo import fib, fib2
>>>fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
这不会把模块名导入使用者的符号表中(例如,上面例子中fibo就没有定义)。
还有一种办法可以导入一个模块中定义的所有名字:
>>>from fibo import *
>>>fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
这可以把模块中除了以下划线结尾的所有名字导入。
6.1.1 模块搜索路径
在导入名为spam的模块时,解释程序先在当前目录中寻找名为“spam.py”的文件,然后
从环境变量PYTHONPATH所定义的目录列表中寻找。PYTHONPATH的用法和可执行文件的搜
索路径PATH用法相同,都是一个目录列表。当PYTHONPATH未设置的时候,或者文件仍找
不到,则搜索继续在安装时设定的缺省路径搜索,在Unix中,这通常是“.:/usr/local
/lib/python” 。
实际上,模块是按变量sys.path指定的路径搜索的,此变量在解释程序启动时初始化为
包含输入脚本的目录(或当前路径),PYTHONPATH和安装缺省路径。这样,用户可以通
过修改sys.path 来修改和替换模块搜索路径。参见后面关于标准模块的一节。
6.1.2 “编译”的Python文件
为了提高调用许多标准模块的小程序的启动时间,一个重要的措施是,如果在找到“sp
am.py ”的目录中存在一个名为“spam.pyc”的文件,就认为此文件包含了模块spam的
一个所谓“ 字节编译”版本。用于生成“spam.pyc”的“spam.py”的修改时间被记入
了“spam.pyc”中,如果记录的修改时间与现在文件的时间不相符的话就忽略编译文件
。
一般不需要自己生成“spam.pyc”这样的编译文件。每当“spam.py”成功编译后解释程
序就尝试写编译版本“spam.pyc”,如果不可写也不会出错;如果因为某种原因此文件
没有写完则生成的“spam.pyc”被识别为不完整的而被忽略。编译文件“spam.pyc”的
格式是不依赖于平台的,所以不同结构的机器可以共享Python模块目录。
下面是对专家的一些窍门:
如果Python解释程序是以-O标志启动的,将生成优化的编译代码,保存在“.pyo”文件
中。目前优化不是很多,现在只是去掉assert语句和SET_LINENO指令。使用了-O标志时
,所有字节码都是优化的,“.pyc”文件被忽略,“.py”文件被编译为优化的字节码。
给Python解释程序两个优化标志(-OO)产生的优化代码有时会导致程序运行不正常。目
前双重优化只从字节码中删除了__doc__字符串,使得“.pyo”文件较小。有些程序可能
是依赖于文档字符串的,所以只有在确知不会有问题时才可以使用这样的优化。
从“.pyc”或“.pyo”读入的程序并不能比从“.py”读入的运行更快,它们只是调入速
度更快一些。
如果一个程序是用在命令行指定脚本文件名的方式运行的,脚本的字节码不会写入“.p
yc ”或“.pyo”文件。所以如果把程序的主要代码都移入一个模块,脚本中只剩下导入
该模块的引导程序则可以略微缩短脚本的启动时间。
可以有叫做“spam.pyc”(当用了-O标志时为“spam.pyo”)的文件而没有对应的源文
件“spam.py”。这可以用来分发一个比较难反编译的Python代码库。
模块compileall可以把一个目录中所有模块编译为“.pyc”文件(指定了-O选项时编译
为“.pyo”文件)。
6.2 标准模块
Python带有一个标准模块库,在另一个文档《Python库参考》中进行了描述。一些模块
直接编入了解释程序中,这些模块不是语言的核心,为了运行效率或者为了提供对于系
统调用这样的系统底层功能而编入了解释程序中。提供那些模块是编译时的选择,例如
,amoeba模块只在提供amoeba底层指令的系统中才能提供。
有一个模块值得特别重视:sys模块,每一个Python解释程序中都编译入了这个模块。变
量sys.ps1和sys.ps2定义了交互运行时的初始提示和续行提示。
>>>import sys
>>>sys.ps1
'>>>'
>>>sys.ps2
'... '
>>>sys.ps1 = 'C>'
C>print 'Yuck!'
Yuck!
C>
这两个变量只在解释程序以交互方式运行时才有定义。
变量sys.path是一个字符串列表,由它确定解释程序的模块搜索路径。它被初始化为环
境变量PYTHONPATH所指定的缺省路径,环境变量没有定义时初始化为安装时的缺省路径
。可以用标准的列表操作修改这个搜索路径,例如:
>>>import sys
>>>sys.path.append('/ufs/guido/lib/python')
6.3 dir()函数
内置函数dir()用于列出一个模块所定义的名字,它返回一个字符串列表:
>>>import fibo, sys
>>>dir(fibo)
['__name__', 'fib', 'fib2']
>>>dir(sys)
['__name__', 'argv', 'builtin_module_names', 'copyright', 'exit',
'maxint', 'modules', 'path', 'ps1', 'ps2', 'setprofile', 'settrace',
'stderr', 'stdin', 'stdout', 'version']
没有自变量时,dir()列出当前定义的名字。
>>>a = [1, 2, 3, 4, 5]
>>>import fibo, sys
>>>fib = fibo.fib
>>>dir()
['__name__', 'a', 'fib', 'fibo', 'sys']
注意dir()列出了所有各类名字:变量名、模块名、函数名,等等。dir()不会列出内置
函数、变量的名字。要想列出内置名字的话需要使用标准模块__builtin__:
>>>import __builtin__
>>>dir(__builtin__)
['AccessError', 'AttributeError', 'ConflictError', 'EOFError', 'IOError',
'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
'MemoryError', 'NameError', 'None', 'OverflowError', 'RuntimeError',
'SyntaxError', 'SystemError', 'SystemExit', 'TypeError', 'ValueError',
'ZeroDivisionError', '__name__', 'abs', 'apply', 'chr', 'cmp', 'coerce',
'compile', 'dir', 'divmod', 'eval', 'execfile', 'filter', 'float',
'getattr', 'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'len', 'long',
'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'range', 'raw_input',
'reduce', 'reload', 'repr', 'round', 'setattr', 'str', 'type', 'xrange']
6.4 包
Python中可以用“包”来组织Python的模块名字空间,名字引用时可以用“带点的模块
名。例如,模块名A.B代表包“A”内名为“B”的子模块。正如使用模块可以使不同模块
的作者不用顾虑彼此的全局变量名会冲突,使用带点的模块名可以使多模块包如NumPy和
PIL的作者不需要担心彼此的模块名会冲突。
假设你有一系列处理声音文件和声音数据的模块(称为一个“包”)。有许多种不同的
声音文件格式(通常用扩展名来识别,如“wav”,“.aiff”,“.au”),所以你可能
需要制作并维护一组不断增加的模块来处理不同文件格式的转换。你还可能需要对声音
数据进行许多不同的操作(如混音、回响、均衡、产生模拟立体声效果),所以你还需
要不断增加模块来执行这些操作。一下是你的程序包的可能的结构(用一个分层文件系
统表示):
Sound/ 顶层包
__init__.py 初始化音响包
Formats/ 用于文件格式转换的子程序包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
Effects/ 用于音响效果的子程序包
__init__.py
echo.py
surround.py
reverse.py
...
Filters/ 用于滤波的子程序包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
包目录中的“__init__.py”文件是必须得,用来指示Python把这个目录看成包,这可以
防止有相同名字如“string”的子目录掩盖住在搜索路径后面一些出现的模块定义。在
最简单的情况下,“__init__.py”可以是一个空文件,它也可以包含初始化包所需的代
码,和设置“__all__”变量,这些后面会加以讨论。
包的用户可以从包中导入单独的模块,如:
import Sound.Effects.echo
这可以把子模块Sound.Effects.echo导入。要引用它也必须用全名,例如:
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)
导入子模块的另一种办法是:
from Sound.Effects import echo
这同样也导入子模块echo,但调用时不需写包前缀,所以可以用如:
echo.echofilter(input, output, delay=0.7, atten=4)
另外一种写法是直接导入所需的函数或变量:
from Sound.Effects.echo import echofilter
这一次同样是调入了子模块echo,但是使其函数echofilter直接可用:
echofilter(input, output, delay=0.7, atten=4)
注意使用“from 包 import 项”这样的格式时,导入的项可以是包的一个子模块(或子
包),也可以是包内定义的其它名字如函数、类、变量。导入语句首先查找包内是否定
义了所需的项,如果没有则假设它是一个模块然后调入。如果找不到,结果引起Import
Error。
相反的,当使用“import item.subitem.subsubitem”这样的格式时,除最后一个外其
它各项都应该是包,最后一项可以是包也可以是模块,不允许是前面一项内部定义的类
、函数或变量。
6.4.1 从包中导入*
现在,如果用户写“from Sound.Effects import *”会发生什么情况?理想情况下我们
希望这应该扫描文件系统,找到所有包内的子模块并把它们都导入进来。不幸的是这种
操作在Mac和Windows平台上不能准确实现,这两种操作系统对文件名的大小写没有准确
信息。在这些平台上,不知道名为“ECHO.PY”的文件会作为模块echo、Echo还是ECHO被
导入。(例如,Windows 95在显示文件名时总是讨厌地把第一个字母大写)。DOS的8+
3文件名限制更是对长模块名造成了有趣的困难。
这个问题的唯一解决办法是由模块作者显式地提供包的索引。引入*的import语句遵循如
下规定:如果包的“__init__.py”文件定义了一个名为“__all__”的列表,这个列表
就作为从包内导入*时要导入的所有模块的名字表。因此当包的新版本发布时需要包的作
者确保这个列表是最新的。包的作者如果认为不需要导入*的话也可以不支持这种用法。
例如,文件Sounds/Effects/__init__.py 可以包含如下代码:
__all__ = ["echo", "surround", "reverse"]
这意味着from Sound.Effects import *将从Sound包中导入指定的三个子包。
如果没有定义__all__,则from Sound.Effects import *语句不会导入Sound.Effects包
中的所有子模块;此语句只能保证Sound.Effects被导入(可能是执行其初始化代码“_
_init__.py ”)并导入包中直接定义的名字。这包括由“__init__.py”定义的任何名
字和显式导入的子模块名。这也包括模块中已经在前面用import显式地导入的子模块,
例如:
import Sound.Effects.echo
import Sound.Effects.surround
from Sound.Effects import *
在这个例子中,echo和surround模块被导入当前名字空间,因为它们在执行from...imp
ort 语句时已定义(在定义了__all__的情况下这一点也是成立的)。
注意用户应尽量避免使用从模块或包中导入*的做法,因为这样经常导致可读性差的代码
。尽管如此,在交互运行时可以用导入*的办法节省敲键次数,而且有些模块在设计时就
考虑到了这个问题,它们只输出遵循某种约定的名字。注意,from 包 import 特定子模
块的用法并没有错,实际上这还是我们推荐的用法,除非程序还需要用到来自其它包的
同名的子模块。
6.4.2 包内部引用
子模块常常需要彼此引用。例如,模块surround可能要用到模块echo。事实上,这样的
引用十分常见,所以import语句首先从子模块的所在包中寻找要导入的子模块才在标准
模块搜索路径查找。所以,模块surround只要写import echo或from echo import echo
filter。如果在包含本模块的包中没有找到要导入的模块,import语句将去寻找指定名
字的顶级模块。
当包组织成子包时(比如例中的Sound包),没有一种简单的办法可以引用兄弟包中的子
模块――必须使用子模块的全名。例如,如果模块Sound.Filters.vocoder要引用Sound
.Effects 包中的echo模块,它可以用Sound.Effects import echo。
通过执行类代码体创建或扩展类Class的对象
ruby 代码
class [scope::] classname [
body
end
注意:
1、如果superexpr存在,那么该superexpr应当是一个以Class对象为结果的表达式,而且它将是被定义的类的超类。
如果省略superexpr,则默认为类Object
2、所有类定义是在代码执行时候生成的。
3、所有类定义在执行后都是一个Class类的对象。
4、所有的这些对象都将赋给名为classname的常量。
5、使用域作用符(::)可以为类定义中的classname前置一个已存在的类或模块名。这样会将新的定义插入到前面定义
的模块和/或类的名字空间中,但不是在这些外部类的作用域中解释此定义。前面带有域作用符的classname将被放置在
那个类或模块所处的顶层(这样作有个什么好处)
方式二、匿名类
ruby 代码
class <<obj
body
end
该类是一个匿名类,将会和指定的对象关联。这时这个匿名类将是该关联对象的虚拟类,原来该对象的类,变成了该虚拟 类的超类。
注意:如果直接在类定义外,给你对象新增一些方法和这样为一个对象创建一个类是等价的。同样是创建一个虚拟类。
Ruby类定义和其他语言不一样,其他语言都是在编译期处理的。而ruby是在代码运行时候根据类的定义创建的。这样如下特点:
1、可以在运行时候决定类的定义。这样根据不同条件,得出不同的类的定义结构
2、如果类定义是可执行的代码,那么它一定是在某个对象的上下文中执行的。Ruby中直接把该类作为当前对象
3、这个对象的类属于Class。说明,所有创建类就是一个对象,他们的类就是Class
太多了!对不起!没有给您找完
第1代:CRV1:
MEIKO
年龄:20+岁(另有亚种咲音メイコ ,现16岁,与MEIKO并非同一人)
发售日:04.11.5
声源:拜乡芽衣子
擅长曲风:流行曲、摇滚乐、爵士乐、R&B、童谣
萌点:酒、耳机
这个就是官方最初人设啦!“手拿麦克风,充满朝气的女孩”……不过其实是个暴力女。公认的大姐,虽无确切年龄设定,但比KAITO要年长,不折不扣的御姐。还有喜欢喝酒之类的设定也都是在初音火了之后才被设定的呢~
腹黑双子RIN·LEN唯一不敢招惹的人,传说中最强的长女!
CRV2:KAITO (姓始音--为同人设定产生的姓氏)(爱称:うた的哥哥)
年龄:20岁 (非官方设定)
发售日:06.2.17
声源:风作为雅||
擅长曲风:民谣、童谣、POP
萌点:冰激凌、围巾
天然呆,FANS爱称为大哥。首个日本语男声音声合成歌唱软件!酷爱冰淇淋,常备正露丸(腹泻药),静冈出身,戴上眼镜会变鬼畜。
第2代:
CV01:(Hatsune Miku)(初音未来)
年龄:16岁
发售日:07.8.31
声源:藤田咲
擅长曲风:80年代至最新的流行歌曲初音未来
萌点:葱、双马尾
初音:“最初的声音”“出发点” “最初的VOCALOID2”
“未来”,指“VOCALOID所象征的将来音乐之可能性”
整套系列最出名的初音!身高158体重42
声音激萌的甜美少女!不过VOCALOID想创造的完美虚拟偶像也被一首“甩葱歌”弄得破灭了~
不过从另一个层面来看,《甩葱歌》也算是初音未来的成名曲。不少网友是在听过这首歌之后成为她的粉丝。
CV02镜音双子
镜音铃/钟
镜音连/怜
年龄:14岁
发售日:07.12.27
擅长曲风:摇滚、电声音乐、舞蹈、歌谣曲、演歌系的流行曲
声源:下田麻美
萌点:橘子(Rin)香蕉(Len)、压路机
镜音:关键字“镜音”想给别人表达的是一种“镜面反射之音”的印象。另一种带有性别意思的内容则为“镜子中映射出另一个异性的自己”的概念。
两位角色的名字先从镜音Rin开始介绍,(Rin)用汉字可以用“钟”或“铃”等汉字代替,给人一种“呼唤众人的人”的印象。而(Len)应该是铃的第二性别人格,汉字直接可以写为“连”,有一种“成行的存在”的意思,另外可以将片名变换为罗马注音“Rin”、“Len”,其中也包含了“LR(左右)”的意义。
身高:156;体重:47。
设定却没有LOLI和正太那么纯真可爱,他们怀着以下克上的野心,开着压路机横冲直撞,有些天然呆的姐姐MIKU和根本就是天然呆的哥哥KAITO都成了他们欺凌的对象。
CV03:LUKA(巡音露卡/流歌/流香)
年龄:20岁
发售日:09.1.30
声源:浅川悠
擅长曲风:拉丁音乐 爵士到民族系流行音乐/家庭到电子系舞曲
象征物:章鱼、鲔
巡音:名字和构想呼应着的是『广阔的世界(不同文化间)中巡回的声音、空气感』、『空气的通道(管)』、『移动空间/反射的声音、芳香的印象』的主题。「"巡回"流动的音」
终于出现的官方第三代巡音LUKA!继LOLI正太之后是外冷内热御姐啊!身高162体重45。对于LUKA她这个角色的构想,是有着凛然的眼神、冷艳的雪白肌肤、低温度的沉静的声音的印象组合成。头发颜色的由来是当吹奏管乐器时,奏者吐息高扬而引起的双颊桃红的样子,以从头部生长出的“粉红色头发”来表示其含义。她的沉静内有着热情的温度,这便是从她体内引出的想象。