Python中的下划线的用法介绍

Python中的with…as用法介绍,pythonwith…as

这个语法是用来代替传统的try…finally语法的。
复制代码 代码如下:
with EXPRESSION [ as VARIABLE] WITH-BLOCK

基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。

紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。
复制代码 代码如下:
file = open(“/tmp/foo.txt”)
try:
    data = file.read()
finally:
    file.close()

使用with…as…的方式替换,修改后的代码是:
复制代码 代码如下:
with open(“/tmp/foo.txt”) as file:
    data = file.read()
#!/usr/bin/env python
# with_example01.py
 
 
class Sample:
    def __enter__(self):
        print “In __enter__()”
        return “Foo”
 
    def __exit__(self, type, value, trace):
        print “In __exit__()”
 
 
def get_sample():
    return Sample()
 
 
with get_sample() as sample:
    print “sample:”, sample

执行结果为
复制代码 代码如下:
In __enter__()
sample: Foo
In __exit__()

  1. __enter__()方法被执行
  2. __enter__()方法返回的值 – 这个例子中是”Foo”,赋值给变量’sample’
  3. 执行代码块,打印变量”sample”的值为 “Foo”
    澳门威斯尼人平台登录 ,4.
    __exit__()方法被调用with真正强大之处是它可以处理异常。可能你已经注意到Sample类的__exit__方法有三个参数-
    val, type 和
    trace。这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。

这个语法是用来代替传统的try…finally语法的。 复制代码 代码如下: with
EXPRESSION [ as VARIABLE] WITH-BLO…

单划线(_)

第一形式
# !/usr/bin/env python
# coding=utf-8

最近要回学校开始做毕设了,准备做个有关算法的,听说python运算好一些,特地来学一学。

先从基础开始啊…………………………

Python中比较两个对象是否相等,一共有两种方法,简单来说,它们的区别如下:

在解释器中

class Person(object):
#object表示继承自object类,Python3中可省略次内容
    “””
    This is a sample of Class
    “””
    breast = 90  #类的属性 是静态变量
   
    def __init__(self, name): #初始化方法  self为对象实例本身
        self.name = name
       
    def get_name(self):  #类的方法
        return self.name
   
    def color(self,color):
        d = {}
        d[self.name] = color;
        return d
   
if __name__ == “__main__”:
    girl = Person(“songjia”)
    print girl.name
    girl.name =”liu”
    print girl.get_name()
    print girl.color(“white”)
    girl.breast = 80 #修改实例的属性
    print girl.breast
    print Person.breast #类属性不会随实例属性的改变而改变
    Person.breast = 100
    print Person.breast
    print girl.breast
第二种形式
>>> __metaclass__ = type
>>> class CC:
…     pass

>>> cc = CC()
>>> cc.__class__
<class ‘__main__.CC’>
>>> type(cc)
<class ‘__main__.CC’>
实例

函数

可以直接从Python的官方网站查看文档:

 

1.在Python提示符下,输入下面语句,就会显示Python提供的内置函数列表
>>>dir(‘__builtins__’)

>>>abs(_)

内置函数,绝对值或复数的模。

>>>chr()

以单字节整数为参数,返回一个单字符的字符串,其内容是与之对于的ASCII字符。如chr(69)返回’E’。

>>>cmp()

比较字符串,cmp(‘Xiao’,’Jian’)返回1

>>>coerce()

(可以看成一个数值类型转换函数)有两个参数,都是数字,返回这两个数字的一个列表,将这两个数字的数据类型统一。如coerce(1,2j),返回(1+0j,2j)

>>>complex()

内置函数,把……转换成复数,如complex(‘2’)返回(2+0j),complex(‘2+3j’)返回(2+3j)。

>>>divmod()

内置函数,有两个参数,返回(商,余数)。如divmod(10,2.5),返回(4.0,0.0)。

>>>filter(function,list)

把函数应用于list中的每一项,并返回
从函数中返回真值的项。注:function可以为None,此时删除list中的0或空项。

>>>float()

内置函数,把……转换成浮点数。

>>>floor()

在math模块内,需要import
math。向下取整,即向x轴负方向取整。如math.floor(1.9)返回1,math.floor(-2.5)返回-3。

>>>hash()

散列功能,词典键的最精确功能需求是它一定是可散列的。对象的散列值是半唯一的、内部生成的数字,它可用于快速比较。

>>>int()

内置函数,把字符串或者小数转换为一个整数。直接去掉小数部分。如int(5.3)返回5,int(‘5’)返回5。

>>>len(x)

序列x的长度

>>>long()

内置函数,把数字 或 代表整数的字符串 转换成长整型

>>>map(function,list[,list,…])

>>>max()

找出字符串中最大的字符。如:min(‘find the minimum character’),返回’
‘,即空格。

>>>min()

找出字符串中最小的字符。如:max(‘find the maximum character’),返回’x’。

>>>oct()

将十进制数转换成八进制,再变成字符。

>>>ord()

参数是单个的ASCII字符,返回该ASCII字符对应的整数值,如ord(‘a’)返回97。

>>>pow()

内置函数,乘方。如果有第三个参数,则表示乘方的结果对第三参数取余,如pow(2,3)返回8,pow(2,3,4)返回0。

>>>print

输出到窗口

>>>range()

生成一个向量,例如range(m,n,d),从m到n,步长为d;range(m)则生成0:m-1,步长为1的向量。

>>>raw_input()

输入函数,参数为字符串,作为输入时的提示语句。返回值为字符串。

>>>reduce(func)

>>>round()

内置函数,对数字进行四舍五入,第二个参数表示精确到小数点后指定的位数,默认值为0。如round(2.4)返回2,round(1.398,2)返回1.40。

>>>type()

返回某数据的类型

 

************************************************************************************************************* 

2.在Python中,定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。

 

3.
Python的函数可以返回多值,其实就是返回一个tuple,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,但写起来更方便。

 

4.递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

 

5.函数的默认参数的作用是简化调用,你只需要把必须的参数传进去。但是在需要的时候,又可以传入额外的参数来覆盖默认参数值。

我们可以把 n 的默认值设定为 2:

def power(x, n=2):

这样一来,计算就不需要传入两个参数了:

由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面:

 

6.如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数:

def fn(*args): print args

可变参数的名字前面有个 * 号,我们可以传入0个、1个或多个参数给可变参数:

可变参数也不是很神秘,Python解释器会把传入的一组参数组装成一个tuple传递给可变参数,因此,在函数内部,直接把变量 args看成一个 tuple 就好了。

定义可变参数的目的也是为了简化调用。假设我们要计算任意个数的平均值,就可以定义一个可变参数:

def average(*args):

 

is 是比较两个引用是否指向了同一个对象(引用比较)。
== 是比较两个对象是否相等。
>>> a = [1, 2, 3]
>>> b = a
>>> b is a #
a的引用复制给b,他们在内存中其实是指向了用一个对象
True
>>> b == a # 当然,他们的值也是相等的
True
>>> b = a[:] #
b通过a切片获得a的部分,这里的切片操作重新分配了对象,
>>> b is a # 所以指向的不是同一个对象了
False
>>> b == a # 但他们的值还是相等的
True
实现原理

在解释器中,_代表交互式解释器会话中上一条的执行结果。这种用法有点类似于Linux中的上一条命令的用法。只不过在在Python解释器中表示的上一条执行的结果。

girl = Person(“songjia”)
类属性

is 比较的是两者是否是同一个对象,所以比较的是内存地址(id是否相同)。

>>> “alright”
‘alright’
>>> _
‘alright

>>> class A(object):    #Python 3: class A:
…         x = 7  #类的属性

下面列出类的几种特殊属性的含义:

==
是值比较。不可变对象,例如int,str,它会直接进行值比较。对于Python已知的对象,会调用他们的
__eq__ 函数来比较。(其实已知的对象应该也是通过内置的 __eq__
函数来比较的)。对于自定义的对象,如果实现了 __eq__
函数,就会使用它比较,如果没有实现,效果和 == 是一样的。

作为一个名称

C.__name__
:以字符串的形式,返回类的名字,注意这时候得到的仅仅是一个字符串,它不是一个类对象
C.__doc__ :显示类的文档
C.__base__ :类C的所有父类。如果是按照上面方式定义的类,应该显示
object
,因为以上所有类都继承了它。等到学习了“继承”,再来看这个属性,内容就丰富了
C.__dict__ :以字典形式显示类的所有属性
C.__module__ :类所在的模块
实例属性

对象缓存机制

作为临时性的名称使用,但是在后面不会再次用到该名称。这种用法在循环中会经常用到。

>>> class A(object):    #Python 3: class A:
…         x = 7  #类的属性

>>> foo = A()
>>> foo.x #实例属性
类中变量引用可变数据

Python会对比较小的对象缓存,下次用到比较小的对象时,会去缓存区查找,如果找到,不会再开辟新的内存,而是继续把小对象的地址赋给新的值。例子:

for _ in range(10):
    do_something()

>>> class B(object):
…     y = [1, 2, 3]
   
   >>> B.y         #类属性
[1, 2, 3]
>>> bar = B()
>>> bar.y       #实例属性
[1, 2, 3]

>>> c = 1
>>> d = 1
>>> print(c is d)
True
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
通过计算得到的赋值,不会使用缓存区。从第一个代码示例中可以看出。

作为函数的连接符,仅仅是一种函数名的命名方式,就如同Java的驼峰式的命名法是一样的。

>>> bar.y.append(4)
>>> bar.y
[1, 2, 3, 4]
>>> B.y
[1, 2, 3, 4]

对于字符串,你可以通过使用 intern 函数强制使用缓存区。

def add_user(user):
 do_something

>>> B.y.append(“aa”)
>>> B.y
[1, 2, 3, 4, ‘aa’]
>>> bar.y
[1, 2, 3, 4, ‘aa’]
当类中变量引用的是可变对象是,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。

名称前的单划线(_get_content)

访问限制

在Python文档中的解释是:以下划线_为前缀的名称(如_get_content)应该被是被API非公开的一部分不管是函数、方法还是属性。此时应该将她们看作一种实现细节,在修改他们的时候无需对外部进行通知。

# !/usr/bin/env python
# coding=utf-8

当使用了以下划线_为前缀的名称,那么在使用from <模块/包名> import
*时,以_开头的名称都不会被导入,除非是模块或包中的__all__列表显式地包含了他们。
由于这种写法仅仅是表示一种细节的实现,在类继承时仍然是可以继承的。

class Person(object):
    “””
    This is a sample of Class
    “””
   
    def __init__(self, name): #初始化方法  self为对象实例本身
        self.__name = name #__xx双下划线表示类的私有变量
       
    def get_name(self):  #类的方法
        return self.__name #类的内部可以访问
   
if __name__ == “__main__”:
    girl = Person(“songjia”)
    print girl.get_name()
    print girl._name #无法访问类的私有变量
文档字符串

class people(object):
    def _eat(self):
        print(‘I am eating’)

在函数、类或者文件开头的部分写文档字符串说明,一般采用三重引号。这样写的最大好处是能够用help()函数看。

class Student(people):
    @property
    def birth(self):
        return self._brith

“””This is python lesson”””

    @birth.setter
    def birth(self,value):
        self._birth = value

def start_func(arg):
   “””This is a function.”””
   pass

    @property
    def age(self):
        return self._age
s = Student()
s._eat()    #输出: I am eating

class MyClass:
   “””This is my class.”””
   def my_method(self,arg):
       “””This is my method.”””
       pass
继承

名称前的双下划线(如:__run)

单继承

名称前带有双下划线的变量,表示的是一个私有函数,无法被继承,也无法在外部访问。

#!/usr/bin/env python
# coding=utf-8

class People(object):
    def _eat(self):
        print(‘I am eating’)
    def __run(self):
        print(‘I can run’)

class Person(object):        #Python 3: class Person:
    def __init__(self, name):
        self.name = name
   
    def height(self, m):
        h = dict(([“height”, m],))
        return h

class Student(People):
    def torun(self):
       
self.__run()  #出错,因为people的方法无法被继承,在Student中不存在__run()方法

    def breast(self, n):
        b = dict(([“breast”, n],))
        return b

s = Student()
s.torun() 
p = People()
p.__run()    #出错,因为私有函数无法在外部访问

class Girl(Person):  #继承
    def get_name(self):
        return self.name

《Python学习手册》的说明,以双下划线开头的变量名,会自动扩张,从而包含了所在类的名称。例如在Spam类中的X这样的变量名会自动编程_SpamX:原始的变量名会在头部加入一个下划线,然后是所在类名称。

if __name__ == “__main__”:
    cang = Girl(“liuguoquan”)
    print cang.get_name()        #Python 3:
print(cang.get_name()),下同,从略
    print cang.height(160)
    print cang.breast(90)
调用覆盖的方法

dir(People) #输出:_People__run,_eat,…

class Girl(Person):
   def __init__(self, name):
       #Person.__init__(self, name) #调用父类的方法
       super(Girl, self).__init__(name) #调用父类的方法常用写法
       self.real_name = “Aoi sola”

名称前后的双下划线(如init)

   def get_name(self):
       return self.name
      
if __name__ == “__main__”:
   cang = Girl(“canglaoshi”)
   print cang.real_name
   print cang.get_name()
   print cang.height(160)
   print cang.breast(90)

前后有双下划线表示的是特殊函数。通常可以复写这些方法实现自己所需要的功能。最常见的就是复写__init__方法。

执行结果为:

class People(object):
    def __init__(self, arg):
        super(People, self).__init__()
        self.arg = arg

    Aoi sola
    canglaoshi
    {‘height’: 160}
    {‘breast’: 90}
多继承

#!/usr/bin/env python
# coding=utf-8

class Person(object):        #Python 3: class Person:
    def eye(self):
        print “two eyes”

    def breast(self, n):
        print “The breast is: “,n

class Girl(object):        #Python 3: class Gril:
    age = 28
    def color(self):
        print “The girl is white”

class HotGirl(Person, Girl): #多重继承
    pass

if __name__ == “__main__”:
    kong = HotGirl()
    kong.eye()
    kong.breast(90)
    kong.color()
    print kong.age
   
two eyes
The breast is:  90
The girl is white
28
多重继承的顺序-广度优先

class K1(object):        #Python 3: class K1:
   def foo(self):
       print “K1-foo”    #Python 3: print(“K1-foo”),下同,从略

class K2(object):        #Python 3: class K2:
   def foo(self):
       print “K2-foo”
   def bar(self):
       print “K2-bar”

class J1(K1, K2):
   pass

class J2(K1, K2):
   def bar(self):
       print “J2-bar”

class C(J1, J2):
pass
  
if __name__ == “__main__”:
print C.__mro__
m = C()
m.foo()
m.bar()
  
K1-foo
J2-bar
代码中的 print C.__mro__
是要打印出类的继承顺序。从上面清晰看出来了。如果要执行 foo()
方法,首先看 J1 ,没有,看 J2 ,还没有,看 J1 里面的 K1
,有了,即C==>J1==>J2==>K1; bar() 也是按照这个顺序,在 J2
中就找到了一个。

这种对继承属性和方法搜索的顺序称之为“广度优先”。

Python 2的新式类,以及Python 3中都是按照此顺序原则搜寻属性和方法的。

方法

绑定方法

#!/usr/bin/env python
# coding=utf-8

class Person(object):        #Python 3: class Person:
    def eye(self):
        print “two eyes”

    def breast(self, n):
        print “The breast is: “,n

class Girl(object):        #Python 3: class Gril:
    age = 28
    def color(self):
        print “The girl is white”

class HotGirl(Person, Girl): #多重继承
    pass

if __name__ == “__main__”:
    kong = HotGirl() #实例化实现了方法和实例的绑
    kong.eye() #调用绑定方法
非绑定方法

在子类中,父类的方法就是 非绑定方法
,因为在子类中,没有建立父类的实例,却要是用父类的方法。

静态方法和类方法

#!/usr/bin/env python
# coding=utf-8

__metaclass__ = type

class StaticMethod: #静态方法
    @staticmethod
    def foo():
        print “This is static method foo().”

class ClassMethod: #类方法
    @classmethod
    def bar(cls): #类方法必须有cls参数
        print “This is class method bar().”
        print “bar() is part of class:”, cls.__name__

if __name__ == “__main__”:
    static_foo = StaticMethod()    #实例化
    static_foo.foo()               #实例调用静态方法
    StaticMethod.foo()             #通过类来调用静态方法
    print “********”
    class_bar = ClassMethod()
    class_bar.bar()
    ClassMethod.bar()
   
This is static method foo().
This is static method foo().
********
This is class method bar().
bar() is part of class: ClassMethod
This is class method bar().
bar() is part of class: ClassMethod
在python中:

@staticmethod 表示下面的方法是静态方法
@classmethod 表示下面的方法是类方法
多态和封装

多态

class Cat:
   def speak(self):
       print “meow!”

class Dog:
   def speak(self):
       print “woof!”

class Bob:
   def bow(self):
       print “thank you, thank you!”
   def speak(self):
       print “hello, welcome to the neighborhood!”
   def drive(self):
       print “beep, beep!”

def command(pet):
   pet.speak()

pets = [ Cat(), Dog(), Bob() ]

for pet in pets:
   command(pet)
Python中的多态特点,Python不检查传入对象的类型,这种方式被称之为“隐式类型”(laten
typing)或者“结构式类型”(structural
typing),也被通俗的称为“鸭子类型”(duck typeing),Python是弱类型语言。

Java会检查传入对象的类型,所以是强类型语言。

封装和私有化

要了解封装,离不开“私有化”,就是将类或者函数中的某些属性限制在某个区域之内,外部无法调用。

Python中私有化的方法也比较简单,就是在准备私有化的属性(包括方法、数据)名字前面加双下划线。例如:

#!/usr/bin/env python
# coding=utf-8

class ProtectMe(object):        #Python 3: class ProtectMe:
    def __init__(self):
        self.me = “qiwsir”
        self.__name = “kivi” #私有变量

    def __python(self): #私有方法
        print “I love Python.”       

    def code(self):
        print “Which language do you like?”
        self.__python()

if __name__ == “__main__”:
    p = ProtectMe()
    print p.me
    print p.code()
如何将一个方法变成属性调用?

可以使用 property 函数。

#!/usr/bin/env python
# coding=utf-8

class ProtectMe(object):        #Python 3: class ProtectMe:
    def __init__(self):
        self.me = “qiwsir”
        self.__name = “kivi” #私有变量

    def __python(self): #私有方法
        print “I love Python.”       

    @property
    def code(self):
        print “Which language do you like?”
        self.__python

if __name__ == “__main__”:
    p = ProtectMe()
    print p.me
    print p.code #调用方法名即可

发表评论

电子邮件地址不会被公开。 必填项已用*标注