存档: 作者存档:

Python tips: 什么是*args和**kwargs?

没有评论 2011年4月5日

先来看个例子:

def foo(*args, **kwargs):
    print 'args = ', args
    print 'kwargs = ', kwargs
    print '---------------------------------------'

if __name__ == '__main__':
    foo(1,2,3,4)
    foo(a=1,b=2,c=3)
    foo(1,2,3,4, a=1,b=2,c=3)
    foo('a', 1, None, a=1, b='2', c=3)
输出结果如下:

args =  (1, 2, 3, 4)
kwargs =  {}
—————————————
args =  ()
kwargs =  {‘a’: 1, ‘c’: 3, ‘b’: 2}
—————————————
args =  (1, 2, 3, 4)
kwargs =  {‘a’: 1, ‘c’: 3, ‘b’: 2}
—————————————
args =  (‘a’, 1, None)
kwargs =  {‘a’: 1, ‘c’: 3, ‘b’: ’2′}
—————————————

可以看到,这两个是python中的可变参数。*args表示任何多个无名参数,它是一个tuple;**kwargs表示关键字参数,它是一个dict。并且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前,像foo(a=1, b=’2′, c=3, a’, 1, None, )这样调用的话,会提示语法错误“SyntaxError: non-keyword arg after keyword arg”。

 

呵呵,知道*args和**kwargs是什么了吧。还有一个很漂亮的用法,就是创建字典:

    def kw_dict(**kwargs):
        return kwargs
    print kw_dict(a=1,b=2,c=3) == {'a':1, 'b':2, 'c':3}

其实python中就带有dict类,使用dict(a=1,b=2,c=3)即可创建一个字典了。

 

“人生苦短,我用python。”

转自:http://www.cnblogs.com/fengmk2/archive/2008/04/21/1163766.html

 

Django 中 ManyToMany 的关联方法

没有评论 2011年4月4日

什么是 ManyToMany?

举个简单的例子,一本书可以有一个或多个作者,而一个作者可以写多本书,那么对于书和作者来说,他们的关系就不是一一对应的,而是多对多(也就是 ManyToMany)。在 Django 的 model 中,有个 ManyToManyField 专门来处理这种关系。

我写了个小应用来的管理 blog 的文章,因此我设计了这样的 model:

class Tag(models.Model):
    name = models.CharField(max_length=30)

class Entry(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateField(blank=True, null=True)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)

Entry 和 Tag 分别代表了 blog 的两大组件——文章和分类。Tag 很简单,只用一个 name 字段来存放 tag 的名字。而 Entry 则用了 title, pub_date, content 这 3 个字段来存放文章的标题、发布时间和文章内容。那么 tags = models.ManyToManyField(Tag) 是干什么的?

和之前的例子一样,一篇文章会有好几个 tag,而 tag 也下辖很多篇文章。从 Entry 的角度看,它有很多 tag(s),于是通过 ManyToManyField 与 Tag 关联起来。打开数据库,你可以看到 Django 专门生成了名为 entry_tags 的表来保存文章与 tag 的对应关系。

model 是搞定了,但实际中如何使用 model 往数据库里添加文章和 tag? 可以用 Model 的 save 方法或者 Manager 提供的 create 方法向数据库写入数据,因此可以这样添加 tag:

t = Tag()
t.name = '测试'
t.save()

# 或者
Tag.objects.create(name='测试')

文章也是一样:

e = Entry()
e.title =  '测试'
e.pub_date = '2010-03-11'
e.content = 'test'
e.save()

但这样只能分别添加 tag 和文章,而且文章与 tag 的对应关系没有添加进去。要想在添加文章的时候顺便把 tag 和对应关系也一并存放,我们需要重载 save 方法:

class Entry(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateField(blank=True, null=True)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)
    taglist = []

    def save(self, *args, **kwargs):
        super(Entry, self).save()
        for i in self.taglist:
            p, created = Tag.objects.get_or_create(name=i)
            self.tags.add(p)

在 Entry 的属性里多了个 taglist,它用来储存文章的 tag。之后使用 save 的时候,会先调用 Entry 父类的 save 方法将 title, pub_date, content 写入 entry 表,然后取出 taglist 中的每一个 tag,调用 Tag.objects.get_or_create 方法获得 Tag 对象,再用 ManyToMany 的 add 方法添加 Tag 对象,最后二次调用 save 方法把数据真正存入数据库

Manager 的 get_or_create 方法接受给定参数作为查询条件,如果找到结果就返回找到的对象,如果没找到就先创建对象再返回它,这样一来我们就不用担心会出现重复添加 tag 的问题了。

能否在添加的文章的时候也使用 get_or_create 方法来防止重复添加呢,答案是当然可以。自定义一个 Manager 重载 get_or_create 即可。

class EntryManager(models.Manager):
    def get_or_create(self, **kwargs):
        defaults = kwargs.pop('defaults', {})
        taglist = defaults.pop('taglist', {})
        Entry.taglist = taglist
        kwargs.update(defaults)
        super(EntryManager, self).get_or_create(**kwargs)

class Entry(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateField(blank=True, null=True)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)
    taglist = []
    objects = EntryManager()

    def save(self, *args, **kwargs):
        super(Entry, self).save()
        for i in self.taglist:
            p, created = Tag.objects.get_or_create(name=i)
            self.tags.add(p)
        self.taglist = []

因为 get_or_create 实际上还是会最终调用 model (Entry) 的 save 方法,所以才会用Entry.taglist = taglist 在真正执行 get_or_create 之前先把 tag 放进去。

最后就可以这样储存文章:

title = '测试'
data = {'taglist': tags,
        'pub_date': date,
        'content': output,
       }
Entry.objects.get_or_create(title=title, defaults=data)

以上代码均来自 Antidote(https://github.com/Vayn/Antidote),这是一个为方便用 jekyll 写 blog 的人管理文章的应用,欢迎 clone。

 

Django日期的表示方法

1条评论 2011年4月1日

因为开发中经常用到日期的表示方法,而自己又记不住。没办法,好记性不如烂笔头。把他记下来,以后用的时候直接看:

 

%a 星期几的简写
%A 星期几的全称
%b 月分的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年分,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U 第年的第几周,把星期日做为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号

Django数据库模型的字段类型总结

没有评论 2011年3月28日

从网上找了好长时间,总算是找了个差不多。因为经常用,自己又记不住,所以还是总结一下。帮助自己的同时也能帮助别人:

V=models.CharField(max_length=None[, **options])    #varchar

V=models.EmailField([max_length=75, **options])    #varchar
V=models.URLField([verify_exists=True, max_length=200, **options])    #varchar
V=models.FileField(upload_to=None[, max_length=100, **options])    #varchar
#upload_to指定保存目录可带格式,
V=models.ImageField(upload_to=None[, height_field=None, width_field=None, max_length=100, **options])
V=models.IPAddressField([**options])    #varchar
V=models.FilePathField(path=None[, match=None, recursive=False, max_length=100, **options]) #varchar
V=models.SlugField([max_length=50, **options])    #varchar,标签,内含索引
V=models.CommaSeparatedIntegerField(max_length=None[, **options])    #varchar

V=models.IntegerField([**options])    #int
V=models.PositiveIntegerField([**options])    #int 正整数
V=models.SmallIntegerField([**options])    #smallint
V=models.PositiveSmallIntegerField([**options])    #smallint 正整数
V=models.AutoField(**options)    #int;在Django代码内是自增
V=models.DecimalField(max_digits=None, decimal_places=None[, **options])    #decimal
V=models.FloatField([**options])    #real

V=models.BooleanField(**options)    #boolean或bit

V=models.NullBooleanField([**options])    #bit字段上可以设置上null值

V=models.DateField([auto_now=False, auto_now_add=False, **options])    #date
#auto_now最后修改记录的日期;auto_now_add添加记录的日期
V=models.DateTimeField([auto_now=False, auto_now_add=False, **options])    #datetime
V=models.TimeField([auto_now=False, auto_now_add=False, **options])    #time

V=models.TextField([**options])    #text
V=models.XMLField(schema_path=None[, **options])    #text

——————————————————————————–
V=models.ForeignKey(othermodel[, **options])    #外键,关联其它模型,创建关联索引
V=models.ManyToManyField(othermodel[, **options])    #多对多,关联其它模型,创建关联表
V=models.OneToOneField(othermodel[, parent_link=False, **options])    #一对一,字段关联表属性

 

当追寻内心的平静成为奢望

没有评论 2011年3月27日

这两个月来,每天就是开发,算法,版面设计。头都弄的特大!就是这样的一天天过来后才发现,自己的心很乱。确切的说是头很乱,倒不是工作有多难。就是感觉事情特别多,总是有做不完的事情。做完这个又来那个。总之就是从不间断。

偶尔自己也想看看书,平静一下内心。可是一想起繁重的工作,又马上把这个念头去掉了。内心时刻得不到平静。身体也是一直在透支。终于在前几天,我的背痛的厉害,只要一弯腰就痛,连几个小时的睡觉时间都痛。这下可真把我吓坏了,心想估计是长时间不运动,保持一个姿势的原因。没办法,每天早晨硬 是挤出点时间来散步半小时。还别说,两天过去了,背部一点也不痛了。看来最好的运动就是散步了。怪不得好多人喜欢散步。

除了这些,家庭也是让人心烦的一项。因为自己只顾工作,跟本顾及不到家人。所以感情也就慢慢的变淡了。随之而来的就是内战,家庭的不和睦。家庭不和是我最大的困扰。比天天不睡觉还难受。不过,经过我昨晚不眠不休的示好,老婆终算原谅我了。其实两个人生活也无所谓谁对谁错。只要能好好的,快快乐乐的生活就都是对的。反之则双方都有错。就像某位大家说的:“幸福的人都一样,不幸的人却各有各的原因”

最能让我静心的估计就是把自己内心的不开心说出来了。写一篇内心感受的文章胜过我散步好几天。不知道原因是什么,反正结果是非常的好。

关于Django模板不能运算的临时解决办法

1条评论 2011年3月25日

今天用django模板显示数据的时候,想根据数据库内id号取模来实现显示不同的CSS类。结果测试了一天也没运算成功。后来查了大量官方文档才知道,模板是不支持数学运算的(真是个让人绝望的缺陷)。没办法,网站还是要做下去的。只能想想别的办法。

功夫不负苦心人,在用了N多个关键词google了之后。终于找到一条能实现基本功能的替代方法就是:

用django的divisibleby标签实现,如下:

{% for each in somelist %}

{% if forloop.counter0|divisibleby:2 %}

<div class=”class1″></div>

{% else %}

<div class=”class2″></div>

{% endif %}

{% endfor %}

divisibleby标签的意义是用后面的参数去除,除尽为True,否则为False



我家宝宝生病后痛苦的治病经历

3 条评论 2011年2月17日

这两天心情很烦闷,原因无他-我家宝宝生病了。一直的咳嗽,时不时的流点鼻涕,鼻子也不太通。本以为两天就好了,可没想到病情更加的厉害了。

见此情况只好四处求医。先去离我们最近的社区服务器站:大夫给孩子听了听心脏与肺,断定肺内有炎症。但四个月的孩子不好吃药打针,于是给拿了一盒“鲜竹沥”,花了5元。吃了一天。第二天病情更加严重了,便去找大夫寻问原因。居然告诉我说孩子病情比较严重,让我去大医院检查一下。当时真想打他两耳光,看不好就直接说,耽误孩子的病情怎么办。

没办法,我们又改去了给孩子接种疫苗的那家社区服务器站:大夫同样用听诊器给孩子听心脏与肺,然后询问了一下饮食与排便。最后断定,孩子是受惊吓所致。给开了一盒“王氏保赤丸”,然后不知道又用什么在孩子的前胸与后背贴了一贴。共花了60元。没多想就回家了,打开药盒一看,里面有很多小盒-每个小盒里有很多小粒。如果按照医生的药量服用,我家宝宝需要吃两年。第二天,病情同样加重了。又去找医生寻问原因。这次大夫给宝宝化验头发,说是缺钙,同时伴随有病毒性和细菌性感染。医生又重新给开的药-一瓶糖浆和一盒冲剂。同时我还忍痛给我家四个月的宝宝打了一针,大夫说这样好的快。这次共花了150多元。回家一看药品说明书,妈的,又给孩子拿了好几个月的药!第三天,病情没任何好转。去找大夫理论。这回医生又说孩子肺内有炎症,病情比较严重。需要输液!我一听,差点晕过去,也就是说以前是拿我家宝宝练手呢!这次我没同意他们给输液。然后大夫建议我去专门给小孩看病的医院去检查一下。其后,我问他们给开的那么多药怎么办。医生们说:“不要紧,那些药的保质期有好几年,以后生病了还可以吃”。这次我真想杀了她!想想以后疫苗跟体检都在他们这。只能无奈的离开了。心想:现在的医生真够无能的!

在回家的路上,听司机说,附近的村里有一位给小孩看病很好的老中医。无奈之下,只好慕名而去。到了之后,我被吓一跳。这是几间老房子,老到什么程度呢?我担心它会不会突然自己就塌了!不过,与这形成鲜明对比的是来这看病的人很多。我排队一个半小时后,终于见到大夫了。是一个60左右的老头。同样给孩子听心脏和肺(看来这是医生看这种病的通用做法),诊断结果是-我家宝宝得了气管炎。给开了两天的药,说保好。花了5.5元。说实话,我对医生都快丧失信心了。给孩子吃药后,晚上的时候,病情开始好转。也不再吐奶了。这下我的心终于可以放下了。

最后想想,真觉得可悲。正规的社区服务站,居然看不好简单的一个气管炎。而一些私人老大夫确敢保证给看好。

linux下最类似foxmail的邮件客户端软件-claws mail

1条评论 2011年2月13日

在我所使用过的邮件客户端中,无论功能怎么样,觉得最方便的就数foxmail了。最主要的就是设置起来简单。可是windows的病毒实在让人难以忍受。将系统更换为linux后,也有几款不错的邮件客户端。像:Ximian Evolution和ThunderBird。虽然功能不错,不过我总是设置不好,而且也不直观。回复邮件更是不太好。

不过,天无绝人之路,无意间发现了一款最类似foxmail的邮件客户端Claws mail。使用起来与foxmail基本一样。而且功能相当的不错。当然,免费开源是一定的了。还是先来看看我使用时的截图吧:

claws mail

claws mail

怎么样?是不是觉得又回到了foxmail的界面了。

废话不多说了!官方下载地址:http://www.claws-mail.org/downloads.php

如果是linux的用户可以直接在线安装,我即是用新立得自动安装的。因为是跨平台软件,所以,windows下的客户也可以体验一下。

好用的免费理财软件kmymoney

5 条评论 2011年1月14日

结婚一年来终于意识到金钱的重要性了。正所谓你不理财,财不理你。眼看越来越紧张的生活,不得不好好管理一下财务了。为了对家庭的财务流向有个好的认识。上次买了个记账本专门记帐。没想到记了两天就坚持不下去了。财务数据算来算去,一点到不明了。而且还非常的不好记,估计不是专业会计的原因。无奈之下,只好放弃了。实在舍不得在上面花费太大精力。

最近这几天真应了那句“花钱如流水”。处处需要钱,由于名目繁多,我都记不住了。眼看着钱一点一点的少,就是不知道去那了。也不知道家里现在是赢利还是亏空。在网上也没找着合适的理财软件。也许是精诚所至吧,居然无意中发现一款非常适合我的理财软件kmymoney。最关键是它的易用性和强大的功能。无论是家庭消费理财还是商业投资都能胜任。更让人高兴的还是他的开源免费。

官方网站下载地址:http://kmymoney2.sourceforge.net/index-home.html

因为它是多平台的,所以各个平台上都有相应的版本。不过,个人觉得还是在linux下运行的版本比较好。在加上它内含多种国家语言包。人性化的设计。基本没有使用难题。对于精准的跟踪个人财务走向是个不错的选择。

这个社会很现实

1条评论 2011年1月13日

一直默默的工作看来不是什么好事。当你为别人着想的时候,别人不一定为你着想。难道真是自己的人品为题?老婆生完孩子的这两个月来,我一直在家帮别人开发网站。也算是默默的付出吧。报酬连提也没提。对方也只是一直在夸我是个干事业的人,也跟我一样没提。当然自己不缺这方面时也就没在意。

好景不长,年底我妹、老婆她妹、老婆他哥都结婚。每人礼钱一万。这下可真把我难住了。没办法,我们结婚时老婆她哥给了一万,回礼总不能少吧。都给她哥一万了,她妹自然也是这样。没办法,只好找跟我合作的公司去问问看能不能借点来。很不巧,对方说自己刚买了房子,还在借钱。总之还说了一堆好听的,我还能怎么办。人家这是不给呗!没办法又去另外一家,看看能不能预支两万工资。本来想,要是真给我预支让我渡过年关的话,以后就算不拿钱也给他们做。很可惜的是对方给我了一份合同。限制了我很多行动,自我感觉跟卖身没什么区别了。于是思虑再三,还是决定不签了,同时心里也预感到了不可能预支出钱来。 继续阅读…