1、先按照参数的位置传递。
2、再按照参数的关键字传递。
3、最后按包裹的形式传递。注意定义函数时参数有默认值,则带有默认值的参数必须跟在必选参数的后面。
实例
1
2
3
4
5
6
7
8
func(1,2) # 按位置传递方式将1、2赋值给a、b,c采用默认值0
a=1 b=2 c=0 args = () kw = {}
func(1, 2, c=3) # 按位置传递方式将1、2赋值给a、b,将3赋值给c
a=1 b=2 c=3 args = () kw = {}
func(1, 2, 3, 'a', 'b')
a=1 b=2 c=3 args = ('a', 'b') kw = {}
func(1, 2, 3, 'a', 'b', x=99)
a=1 b=2 c=3 args = ('a', 'b') kw = {'x': 99}
以上就是python混合传递的基本原则,
002-PG002-Python002 中英文混合字符串的对齐
最近几天在研究tkinter的颜色名称,准备写个能展示所有支持的颜色名的小程序。
做着做着发现一个问题,tkinter的listbox不支持多列的list,我那个表有6列,自己写一个class又好烦,于是就想到干脆加点竖线或者制表符排个版对齐一下,看着像表就行了。
于是又遇到一个问题,里面的中文名是我自己翻译的,有一些是中文+数字的组合,Python是对于汉字和英文都算作1个字符的,len('一二三abc')输出是6,而汉字和英文的宽度其实不一样,所以用format()和ljust()等函数都无法对齐,制表符在终端里是可以对齐的,但是tkinter迷之不认制表符,填进去完全没用。
然后去tkinter的listbox里测试下
于是自己写了个函数,给定一个字符串和需要的长度,计算一下汉字和字母的个数然后补空格。如下:
随便写个程序测试下
理论上讲应该是正确的,研究了下应该是中英文混排的时候,实际中文字宽不等于2倍英文字宽造成的,包括用全角空格和半角空格补充字符串混排也是对不齐的。
于是我就去找了个中英文混合等宽字体,微软雅黑与Consolas的混合:YaHei Consolas Hybrid,改上去。
顺便说一句,还有个【更纱黑体(Sarasa Gothic)】也不错,但英文太窄了看不习惯,想要的可以去GitHub找到。
完美,问题解决。
边举栗子便说明:1. Perl 使用 Python 中定义的变量
#!/usr/bin/perl -w
use strict
use Inline 'Python' =><<'END'
a = 1
END
print $a
首先从这个栗子我们可以学习Inline::Python的程序布局:一个典型的用法是把Python代码以
use Inline 'Python' =><<'END'
END
这样的Perl多行字符串的形式包裹。当然包裹Python代码的方法还有很多种,详见Inline::Python的文档。
然而不幸的是,这个栗子是行不通的。我们继续往下看。
2 Perl 使用 Python 中定义的函数
代码:
#!/usr/bin/perl -w
use strict
use Inline 'Python' =><<'END'
def Foo(*args):
print "==Python Def=="
for a in args:
print type(a)
print a
END
Foo(1)#[1]
Foo('Hello')#[2]
Foo('Hello','World')#[3]
Foo(('Hello','World'))#[4]
Foo(['Hello','World'])#[5]
Foo({'Hello' =>1,'World' =>2})#[6]
这段代码可以正常运行。在Python区块中定义的函数在Perl中可见。最为关心的是参数传递问题,逐条分析:
#[1] Perl 传入数字,Python也会理解为数字。
#[2] Perl 传入STRING类型,Python会理解为str类型。
#[3] 函数支持多个参数。
#[4] Perl 传入ARRAY值(即@)类型,Python会理解为多个参数。由于在Perl中,HASH值类型(即%)实际上是一种特殊的ARRAY,Python的处理方式应相同。
#[5] Perl 传入ARRAY的引用,Python会理解为list。
#[6] Perl 传入HASH的引用,Python会理解为dict。
返回值的问题同理。
3 传递function引用
有时候需要向Python传递“函数指针”以实现回调。Inline::Python已经照顾到了这种需求:
#!/usr/bin/perl -w
use strict
use Inline 'Python' =><<'END'
def Foo(func):
print type(func)
func({'Hello' : 1,'World' : 2})
END
use Data::Dumper
sub Bar {
print Dumper shift
}
Foo(\&Bar)
它的运行结果:
<type '_perl_sub'>
$VAR1 = {
'World' =>2,
'Hello' =>1
}
Inline::Python为函数引用建立了一个类型_perl_sub。在Python中,这个类型的值可以当成函数对象来使用。
顺便这个例子验证了Python的dict会被Perl理解为HASH引用。
能再复杂一点么?找个对象怎么样?
4 例化Python中定义的类
作为面向对象的语言,Python中很多功能都是以提供类的方式实现的。
看代码:
#!/usr/bin/perl -w
use strict
use Inline 'Python' =><<'END'
class Bar:
def __init__(self,p):
self.p = p
def foo(self,q):
print self.p + q
END
my $bar = Bar->new(1)
$bar->foo(2)
这个例子说明,如果在Python区块中定义了类Bar,那么在Perl环境中就相当于有了一个package Bar。Inline::Python会自动提供一个构造函数new。
说到这里基本的问题差不多都解决了。小伙伴们可以利用Inline::Python,足不出户,在Perl中就可以调用各种稀奇古怪的第三方Python库了。
能不能再复杂点,都OO了……
5 继承Python中定义的类
写这样的代码也不难:
#!/usr/bin/perl -w
use strict
use Inline 'Python' =><<'END'
class Bar:
def __init__(self,p):
self.p = p
def foo(self,q):
print self.p + q
END
package Foo
our @ISA = ('Bar')
sub new {
my $class = shift
my $p = shift
my $self = $class->SUPER::new($p)
return bless $self,$class
}
sub bar {
my $self = shift
my $q = shift
print $self->{p} - $q
}
1
package main
my $foo = Foo->new(1)
$foo->foo(2)
$foo->bar(3)
几个要点需要注意:
1) 用Perl内置的@ISA继承Python提供的类。
2) 用SUPER保留字访问父对象,别忘了和类名bless在一起。
3) 如果父对象定义了变量,用HASH key的方法能访问到。也就是说,Python里的 self.p 相当于 Perl中的 $self->{p}