zoukankan      html  css  js  c++  java
  • Python模块

    • 模块

    在Python中,一个.py文件就称之为一个模块。使用模块可提高外码的可维护性。

    Python内置函数:

    为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。

    自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    'a test module'    #模块的第一个字符串被视为模块的文档注释
    __author__='Larry'
    
    import sys
    
    def test():
        args=sys.argv   #sys模块的argv变量使用list存储了命令行所有参数,argv至少含有一个元素
        #第一个参数永远是该.py文件的名称
        if len(args)==1:
            print('hello,world')
        elif len(args)==2:
            print('hello,%s' % args[1])
        else:
            print('Too many arguments')
    
    if __name__=='__main__':
        test()

    当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

    在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。

    private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量。

    • 面向对象编程
    class Student(object):
        def __init__(self, name, score):
            self.name = name
            self.score = score
    
        def get_grade(self):
            if self.score >= 90:
                return 'A'
            elif self.score >= 60:
                return 'B'
            else:
                return 'C'
    
    tom=Student('Tom',90)
    print(tom.get_grade())  #A

    如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__

    class Student(object):
        def __init__(self, name, score):
            self.__name = name
            self.__score = score
    
        def get_grade(self):
            if self.__score >= 90:
                return 'A'
            elif self.__score >= 60:
                return 'B'
            else:
                return 'C'
    class Student(object):
        def __init__(self, name, score):
            self.__name = name
            self.__score = score
    
        def get_name(self):
            return self.__name
    
        def get_score(self):
            return self.__score
    
        def set_score(self,score):
            if score>=0 and score<=100:
                self.__score =score
            else:
                raise ValueError('Bad score')

    需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

    双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。

    tom =Student('Tom',97)
    tom.__name='tom_new'
    print(tom.get_name())  # Tom
    print(tom.__name)   # tom_new

    表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。

    isinstance()可以判断对象是否属于某种类型。如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。

    实例属性和类属性:

    类的属性归类所有,类的所有实例都拥有该属性。

    class Student(object):
        name='Student'
    
    s=Student()
    print(s.name)  #Student
    print(Student.name)  #Student
    s.name = 'Michael' # 给实例绑定name属性
    print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
    del s.name # 如果删除实例的name属性
    print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了

     使用__slot__

    正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。

    class Student(object):
        pass
    
    s=Student()
    s.name='jack'
    print(s.name)

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

    class Student(object):
        __slots__ = ('name', 'age')  # 用tuple定义允许绑定的属性名称
    
    s=Student()
    s.name='jack'
    s.age=20

    使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的.除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

    • 使用@property

    Python内置的@property装饰器是负责把一个方法变成属性调用的

    把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值:

    class Student(object):
        @property
        def score(self):
            return self._score
    
        @score.setter
        def score(self,value):
            if not isinstance(value, int):
                raise ValueError('score must be an integer!')
            if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
            self._score = value
    
    
    s=Student()
    s.score=66  # OK,实际转化为s.set_score(66)
    print(s.score)  # OK,实际转化为s.get_score()

    还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

    class Student(object):
    
        @property
        def birth(self):
            return self._birth
    
        @birth.setter
        def birth(self, value):
            self._birth = value
    
        @property
        def age(self):
            return 2015 - self._birth

    Python允许多继承

    定制类

    __str__

    class Student(object):
        def __init__(self,name):
            self.name=name
    
        def __str__(self):
            return 'Student object (name:%s)' % self.name
    
    print(Student('Tom'))  #打印实例    Student object (name:Tom)

     枚举类

    from enum import Enum
    
    class Color(Enum):  #枚举定义用class关键字,继承Enum类
        red=1
        orange=2
        yellow=3
        green=4
        blue=5

    定义枚举时,成员名称不允许重复,默认情况下,不同的成员值允许相同。但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名,如果枚举中存在相同值的成员,在通过值获取枚举成员时,只能获取到第一个成员。

    from enum import Enum
    
    class Color(Enum):  #枚举定义用class关键字,继承Enum类
        red=1
        red_alias = 1
        orange=2
        yellow=3
        green=4
        blue=5
    
    print(Color(1))   #Color.red

    使用@unique装饰器,可以限定成员的值不允许相同。

    from enum import Enum,unique
    
    @unique
    class Color(Enum): 
        red=1
        orange=2
        yellow=3
        green=4
        blue=5
    print(Color['orange'])  #Color.orange
    print(Color(2))  #Color.orange

     

  • 相关阅读:
    个人博客08
    《新浪微博平台架构》---阅读
    《阿里游戏高可用架构设计实践》---阅读
    《京东咚咚架构演进》---阅读
    《京东话费充值系统架构演进实践》--阅读
    实时获取input框内容
    html:判断两次密码不一致以及阻止提交
    《京东到家库存系统架构设计》---阅读
    《数据蜂巢架构演进之路》---阅读
    SOA案例分析浅谈
  • 原文地址:https://www.cnblogs.com/larry-xia/p/9094438.html
Copyright © 2011-2022 走看看