显示标签为“Python”的博文。显示所有博文
显示标签为“Python”的博文。显示所有博文

Python Descriptor

在学习Python的过程中,碰到一些奇怪的结果输出,后来参考一些资料后,才知道这是Descriptor特性。现来看一下遇到的问题。


class RevealAccess(object):
def __init__(self,initval,name):
self.val=initval
self.name=name

def __get__(self,obj,objtype):
print "Retrieving:",self.name
return self.val

def __set__(self,obj,val):
print "Updating:",self.name
self.val=val

class C(object):
x=RevealAccess(10,"A test variable")





Case 1:


>>>b = C() # 类C的实例化
>>>b.x # 打印内容
Retrieving A test variable
10
>>> C.x # 输出
Retrieving A test variable
10
>>>




Case 2:


>>>b = C() # 类C的实例化
>>> b.x=100 # 赋值,注意输出结果
Updating A test variable
>>> b.x # 打印内容
Retrieving A test variable
100
>>> C.x # 打印内容
Retrieving A test variable
100
>>>




Case 3:


>>>b = C() # 类C的实例化
>>> C.x=1000 # 同样是赋值,没有输出 Updating A test variable?
>>>
>>> b.x # 没有打印输出Retrieving内容?
1000
>>> C.x # 没有打印输出Retrieving内容?
1000
>>>




Case 4:


>>>b = C() # 类C的实例化
>>> C.x = RevealAccess(999,"The second var") #同样是赋值,没有输出 Updating A test variable?
>>> b.x # 下面有打印输出内容了
Retrieving The second var
999
>>> C.x # 下面有打印输出内容了
Retrieving The second var
999
>>>



以上出现的4种不同情况,引用下文档说明:

The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in the class dictionary of another new-style class, known as the owner class. In the examples below, ``the attribute'' refers to the attribute whose name is the key of the property in the owner class' __dict__. Descriptors can only be implemented as new-style classes themselves.



  1. __get__( self, instance, owner)

    Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute access). owner is always the owner class, while instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner. This method should return the (computed) attribute value or raise an AttributeError exception.


    ps: obj.x、class.x均会导致该调用。


  2. __set__( self, instance, value)

    Called to set the attribute on an instance instance of the owner class to a new value, value.


    ps: 仅obj.x=ttt均会导致该调用;class.x=ttt直接绑定到另外一个对象上,这里x已经不是RevealAccess的实例


  3. __delete__( self, instance)

    Called to delete the attribute on an instance instance of the owner class.





参考建议:为简化以及方面理解,在实际应用中,尽量避免obj.__dict__与class.__dict__拥有同名的属性。


More......

optparse:命令行解析器

强大的命令行解析器,能处理不同形式的命令行参数。

一个简单的例子:


from optparse import OptionParser
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")

(options, args) = parser.parse_args()


现在可以在命令行中这样输入:
< yourscript > --file=outfile -q
parse_args()将返回解析命令行后的结果,这时options.filename=outfile,options.verbose=False。

optparse的强大之处还体现在对如下命令的等价上述解析:
< yourscript > -f outfile --quiet
< yourscript > --quiet --file outfile
< yourscript > -q -foutfile
< yourscript > -qfoutfile


另外,不必在为命令写单独的help函数,可以直接获得帮助信息:
< yourscript > -h
< yourscript > --help


详细的使用方法,参考这里

More......

PyQT学习记录(一)

资源来源于GUI Programming with Python: QT Edition,记录一些学习PyQT的笔记。

什么是PyQT?
PyQT就是 Python+Qt。Qt是一个在linux世界里比较流行的一个图形开发库,用C++实现,另一个比较有名的图形开发库是GTK。PyQT主要是一个Qt的Python接口实现。

如何来开发PyQT?
Eric Python IDE + Qt3 Designer。Eric是Python的利器,目前我使用中的缺陷是调不出中文输入,文件编码格式不支持gbk,所以在输出控制上需要转换为utf8。Qt3 Designer是一个所见即所得的GUI部署工具,类似于VB的图形开发,拖动鼠标即可把GUI界面搭建起来,其比Glade的优势在于可以鼠标定位,Glade主要是开发Gnome界面,Qt3 Designer主要是开发KDE界面,当然在Gnome中运行也是没有问题的。如何快速结合Eric和Qt3来进行图形开发,可以参考这篇文章

入门: “Hello World”


#
# hello1.py
#
import sys
from qt import *
app=QApplication(sys.argv)
button=QPushButton("Hello World", None)
app.setMainWidget(button)
button.show()
app.exec_loop()


运行效果如下图所示:
2007-02-15-124957_582x438_scrot

以下对如上代码加以解释:
(4)sys包的作用是为了能让QApplication类获得可选的命令行参数。比如
python hello.py -style=platinum
那么-style=platinum的作用将使窗口有一个新的look and feel。
(5)为了使用qt中所有的类,本示例中等价于:

from qt import QApplication
from qt import QPushButton

(6)加载了必要的包以后,首先需要创建一个qt工程对象。这个对象用来接受处理所有鼠标和键盘向工程组件(widgets)发送的事件,一般只需要创建一个QApplication就可以了。
(7)利用QPushButton创建了一个按钮对象,一个参数是按钮的caption(按钮上的显示名),第二个参数比较难理解,在QT的layout布局中,所有的组件可以组成一棵树,节点有parent和child。本例中button没有parent,所以设为None
(8)这句话的意思是告诉QApplication,button是一个主组件。
(9)显示button
(10)在application的loop事件被调用之前,界面上不会出现任何东西。

More......