我想我會拼湊一個快速腳本來整合我已經分佈在多個CSS文件中的CSS規則,然後我可以縮小它。Python字典鍵缺失
我是新來的Python,但認爲這將是一個很好的練習來嘗試一種新的語言。我的主循環不像我想的那樣解析CSS。
我使用從CSS文件解析的選擇器填充一個列表以按順序返回CSS規則。在該腳本的後面,該列表包含在字典中找不到的元素。
for line in self.file.readlines():
if self.hasSelector(line):
selector = self.getSelector(line)
if selector not in self.order:
self.order.append(selector)
elif selector and self.hasProperty(line):
# rules.setdefault(selector,[]).append(self.getProperty(line))
property = self.getProperty(line)
properties = [] if selector not in rules else rules[selector]
if property not in properties:
properties.append(property)
rules[selector] = properties
# print "%s :: %s" % (selector, "".join(rules[selector]))
return rules
遇到的錯誤:
$ css-combine combined.css test1.css test2.css
Traceback (most recent call last):
File "css-combine", line 108, in <module>
c.run(outfile, stylesheets)
File "css-combine", line 64, in run
[(selector, rules[selector]) for selector in parser.order],
KeyError: 'p'
交換輸入:
$ css-combine combined.css test2.css test1.css
Traceback (most recent call last):
File "css-combine", line 108, in <module>
c.run(outfile, stylesheets)
File "css-combine", line 64, in run
[(selector, rules[selector]) for selector in parser.order],
KeyError: '#header_.title'
我在做的情況下像子空間代碼中的一些古怪的事情下劃線在字典鍵將其命名爲是一個問題 - 也許這是一個溫和的預防措施?根據輸入的順序,字典中找不到一個不同的鍵。
腳本:
#!/usr/bin/env python
import optparse
import re
class CssParser:
def __init__(self):
self.file = False
self.order = [] # store rules assignment order
def parse(self, rules = {}):
if self.file == False:
raise IOError("No file to parse")
selector = False
for line in self.file.readlines():
if self.hasSelector(line):
selector = self.getSelector(line)
if selector not in self.order:
self.order.append(selector)
elif selector and self.hasProperty(line):
# rules.setdefault(selector,[]).append(self.getProperty(line))
property = self.getProperty(line)
properties = [] if selector not in rules else rules[selector]
if property not in properties:
properties.append(property)
rules[selector] = properties
# print "%s :: %s" % (selector, "".join(rules[selector]))
return rules
def hasSelector(self, line):
return True if re.search("^([#a-z,\.:\s]+){", line) else False
def getSelector(self, line):
s = re.search("^([#a-z,:\.\s]+){", line).group(1)
return "_".join(s.strip().split())
def hasProperty(self, line):
return True if re.search("^\s?[a-z-]+:[^;]+;", line) else False
def getProperty(self, line):
return re.search("([a-z-]+:[^;]+;)", line).group(1)
class Consolidator:
"""Class to consolidate CSS rule attributes"""
def run(self, outfile, files):
parser = CssParser()
rules = {}
for file in files:
try:
parser.file = open(file)
rules = parser.parse(rules)
except IOError:
print "Cannot read file: " + file
finally:
parser.file.close()
self.serialize(
[(selector, rules[selector]) for selector in parser.order],
outfile
)
def serialize(self, rules, outfile):
try:
f = open(outfile, "w")
for rule in rules:
f.write(
"%s {\n\t%s\n}\n\n" % (
" ".join(rule[0].split("_")), "\n\t".join(rule[1])
)
)
except IOError:
print "Cannot write output to: " + outfile
finally:
f.close()
def init():
op = optparse.OptionParser(
usage="Usage: %prog [options] <output file> <stylesheet1> " +
"<stylesheet2> ... <stylesheetN>",
description="Combine CSS rules spread across multiple " +
"stylesheets into a single file"
)
opts, args = op.parse_args()
if len(args) < 3:
if len(args) == 1:
print "Error: No input files specified.\n"
elif len(args) == 2:
print "Error: One input file specified, nothing to combine.\n"
op.print_help();
exit(-1)
return [opts, args]
if __name__ == '__main__':
opts, args = init()
outfile, stylesheets = [args[0], args[1:]]
c = Consolidator()
c.run(outfile, stylesheets)
測試CSS文件1:
body {
background-color: #e7e7e7;
}
p {
margin: 1em 0em;
}
文件2:
body {
font-size: 16px;
}
#header .title {
font-family: Tahoma, Geneva, sans-serif;
font-size: 1.9em;
}
#header .title a, #header .title a:hover {
color: #f5f5f5;
border-bottom: none;
text-shadow: 2px 2px 3px rgba(0, 0, 0, 1);
}
在此先感謝。
對正則表達式'r「」'使用原始字符串文字。你可以使用're.match'而不是're.search(「^ ...'。'return如果x else False可以被'return x'或'return bool(x)'代替,則返回True。 – jfs 2010-06-05 13:26:28