Skip to content

Python

Python简介

  • Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
  • Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构
    • Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
    • Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码
    • Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
    • Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。

Python安装

Python学习

例子代码

#定义学生类
class Student:
    #限定属性范围
    __slots__=('__name','__score','_birthday','_age')
    def __new__(cls,name,score):
        return super().__new__(cls)
    def __init__(self,name,score):
        self.__name=name
        self.__score=score
    def print_score(self):
        print("名字:%s \r\n成绩:%s" %(self.__name,self.__score))    
    @property
    def birthday(self):
        return self._birthday
    @birthday.setter
    def birthday(self,value):
        self._birthday=value
    @property
    def age(self):
        return 2019-self._birthday+1
    #定制类
    def __str__(self):
        return self.__name
    def __call__(self):
        print("call调用年龄:%d"%self.age)

#实例化
if __name__=='__main__':
    tim=Student("tim",100)
    print(Student("test",10))
    tim.birthday=1988
    tim()
    print("年龄:%d"%tim.age)
    tim.print_score()

类和实例

  • 类(Class)和实例(Instance)是面向对象最重要的概念
  • 类是指抽象出的模板。实例则是根据类创建出来的具体的“对象”,每个对象都拥有从类中继承的相同的方法,但各自的数据可能不同。

访问限制

  • 如果想让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以双下划线开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

继承和多态

  • 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
  • 动态语言具有“鸭子类型”的特点,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
  • 动态语言的继承不像静态语言那样是必须的

获取对象信息

  • type() 可以检查类型。
  • isinstance()可以告诉我们,一个对象是否是某种类型
  • 大杀器dir(),可获得一个对象的所有属性和方法

使用slots

**slots**用来限制属性

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

使用@property

  • 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数和确保数据安全
  • 为了确定安全,则可以通过增加setter和getter方法来处理,但是又显得过于复杂了
  • 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
    
  • @property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

多重继承

  • 为了解决单一继承造成的类的数量会呈指数增长,很明显这样设计是不行的,python采取多重继承来解决
  • 在设计类的继承关系时,通常,主线都是单一继承下来的,但是,如果需要“混入”额外的功能,通过多重继承就可以实现,这种设计通常称之为Mixin。
  • 编写一个多进程模式的TCP服务:
    class MyTCPServer(TCPServer, ForkingMixin):
        pass
    
  • 编写一个多线程模式的UDP服务:
    class MyUDPServer(UDPServer, ThreadingMixin):
        pass
    
  • 这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

定制类

  • str_() 用以输出自定义的类打印
    class Student(object):
        def __init__(self, name):
            self.name = name
            def __str__(self):
            return 'Student object (name: %s)' % self.name
    print Student('Michael')
    
  • __iter__用以实现迭代器
    class Fib(object):
        def __init__(self):
            self.a, self.b = 0, 1 # 初始化两个计数器a,b
    
        def __iter__(self):
            return self # 实例本身就是迭代对象,故返回自己
    
        def next(self):
            self.a, self.b = self.b, self.a + self.b # 计算下一个值
            if self.a > 100000: # 退出循环的条件
                raise StopIteration();
            return self.a # 返回下一个值
    
  • __getitem__用以实现获取指定下标的元素并实现切片功能
    class Fib(object):
        def __getitem__(self, n):
           if isinstance(n, int):
                a, b = 1, 1
                for x in range(n):
                    a, b = b, a + b
                return a
            if isinstance(n, slice):
                start = n.start
                stop = n.stop
                a, b = 1, 1
                L = []
                for x in range(stop):
                    if x >= start:
                        L.append(a)
                    a, b = b, a + b
                return L
    
  • __getattr__用以实现动态获取属性的功能
    class Student(object):
        def __init__(self):
            self.name = 'Michael'
        def __getattr__(self, attr):
            if attr=='score':
                return 99
    

枚举类

使用元类

深入理解import和from import的区别

  • 两者的调用方式是不同的
    • 前者是将被导入模块的名称放入当前的模块内;import model
    • 而后者是将被导入的函数或变量名称放入当前操作的模块 from xx import model
  • 举例说明
    • 引用的说明
      #newdemo.py 新创建的py文件中到入模块,并访问模块下方法
      #第一种导入方式
      import module1
      module1.say()
      #第二种导入方式
      from module1 import *
      say()
      
    • from xx import model的使用说明
      #为了防止名称冲突,通过as起一个别名
      from module1 import say as newsay
      def say():
          print("不是导入模块的say")
      say() #自己的
      newsay() #引来的 
      

应用实例

如何发布自己的python包

  • 创建包目录,需要含:py文件夹,setup.py,readme.md,license 注意py文件夹需要包含__init__.py
  • 安装打包工具setuptools:python -m pip install --user --upgrade setuptools wheel
  • 通过setup生成包*dict/*:python setup.py sdist bdist_wheel
  • 安装上传工具twine:python -m pip install --user --upgrade twine
  • 推送到Pypi需注册:python -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/*

Python的GUI编程(Tkinter)

  • 使用Tkinter实现的简单例子
    import tkinter as tk
    root = tk.Tk()
    root.title('顶层窗口')
    #按钮方法
    def btnClick():
        y=float(entry1.get())
        if y % 400 == 0 or (y % 100 == 0 and y % 4 != 0):
            label2.config(text='闰年')
        else:
            label2.config(text='平年')
    #添加控件
    y1=tk.StringVar()
    y1.set('年份')
    tk.Label(root,text='请输入年份',width=10).pack()
    entry1=tk.Entry(root,width=20,textvariable=y1)
    entry1.pack()
    tk.Button(root,text='判断',command=btnClick).pack()
    label2=tk.Label(root, text='', width=10)
    label2.pack()
    root.mainloop()