设为首页 收藏本站
查看: 3491|回复: 0

[经验分享] Python面向对象学习笔记

[复制链接]

尚未签到

发表于 2018-8-15 10:58:17 | 显示全部楼层 |阅读模式
  视频课程《三-Python高级自动化开发工程师微职位:面向对象》
  subprocess模块

  •   用途:如在Linux上调用windows的命令,需要获取命令的输出结果,而不是python代码的结果
  •   与os.system的区别
      输出命令结果到屏幕,返回值是Python代码运行的结果
      subprocess把命令运行的结果和Python代码运行的结果都以元组形式返回,依次读取相应的值即可获得所需数据
  •   Python2中类似的command
os.system("dir")  # 返回状态  

  
os.popen("dir").read()  # 获取结果,但不明确"dir"的运行状态
  

  
# Linux上支持的比较好
  
import commands
  
comands.getstatusoutput("dir") # 以元组形式返回状态值和命令运行的结果
  

  
# Python3.5后出现的方法
  
import subprocess
  
subprocess.run(["df","-h"]) # 形式1
  
subprocess.run("df -h | grep sda1", shell=True) # 形式2
  

  
# Python3.5前的方法
  
subprocess.call(["ls", "-a"]) # 类似与os.system("ls")
  
# 不需要获得命令运行结果,只需指导代码运行状态时
  
subprocess.check_call(["ls", "-l"]) # 返回0或者异常
  
subprocess.getstatusoutput("ls bin/ls") # 返回(0, "/bin/ls")
  
subprocess.output("ls bin/ls") # 返回/bin/ls"
  
subprocess.check_output(["ls", "-a"]) # 返回res,如:b'/bin/ls',并非打印
  底层封装subprocess.popen()方法,返回到res对象中同时还能细分stderror
#res中只包含stdout的输出,从subprocess.PIPE读取而得  
res = subprocess.Popen("ifconfig | grep 192", shell=True, stdout=subprocess.PIPE)
  
res.stdout.read() # 获得stdout的数据
  
res = subprocess.Popen("ifconfig haha | grep 192, shell=True, stdout=subprocess.PIPE,
  
stderr=subprocess.PIPE)
  
res.stdout.read() # 获取运行结果
  
res.stderr.read() # 获取错误信息
  注意,每次调用相当于启动一个新的shell
res = subprocess.Popen("sleep 10; echo 'hi'", shell=True, stdout=subprocess.PIPE)  
res.poll() # 在命令执行完成后返回0,否则一直返回None,这是一个有趣的方法,注意理解
  
#或者可以使用阻塞的方法
  
res.wait() # 等待命令执行完,返回0
  
res.terminate()# 中止执行命令
  

  
res = subprocess.Popen("python3", shell=True, stdout=process.PIPE, stdin=subprocess.PIPE)
  
res.stdin.write("print(1)") # 启动过程中写入数据
  
res.communicate(timeout=10) # 等待结果
  例子:
# python中执行“sudo -S apt-get install vim”注意这个过程需要输入密码  
subprocess.Popen("sudo -S apt-get install vim", shell=True, stdout=subprocess.PIPE) # 出错
  
# 明确命令“echo '1234' | sudo -S apt-get install vim”
  面向对象
  OOP利用类和对象对世界进行描述,使得程序维护和扩展变得简单,提高开发效率,代码容易理解。
  Class类
  抽象出属性的描述和方法。抽象的意义在于化繁为简,更有效率的描述信息。
  Object对象
  类的实例,对象真正存储着属性的值(通常意义上,类属性等除外)
  Encapsulation封装
  在类中对数据赋值、内部调用,外部调用不必也不能对类内进行修改访问。(对外部隐藏对象的工作细节)
  Inheritance继承
  代码复用,以普通类为基础建立专门的类
  Polymorphism多态
  对不同类的对象使用相同的操作,它们会有不同的结果。
  “重复代码是可耻的行为”
  “代码需要经常改动”
  定义
  原则:可读性好,易扩展
class Role(object):  
    def __init__(self, name, role, value, money):
  
        self.name = name
  
        self.role = role
  
        self.life_value = value
  
        self.money = money
  

  
    def shot(self):
  
        print("shooting...")
  

  
    def got_shot(self):
  
        print("ah..., I got shot...")
  

  
    def buy_gun(self, gun):
  
        print("just bought %s", gun)
  

  
    # Python自动调用__del__方法,当对象内存被回收时,将会调用这个方法
  
    def __del__(self):
  
            print("del ...run")
  Python类定义的写法,其实就是执行代码块。
  特性

  •   普通属性(成员变量或字段)
      在__init__()中确定,可以被直接访问和修改,也可以通过方法访问和修改。属于对象的,不同对象不能直接访问。
  •   私有属性
      形如self.__heart,obj.__heart无法外部访问,但实际上可以通过如下方法进行访问
def get_heart(self): # 通过方法访问  
    return self.__heart
  
obj._Role__heart # 通过对象引用直接访问和修改

  •   公有属性
      类的所有实例都可以访问的属性,可以理解为类的属性。如果通过对象的引用修改了同名的公有属性,相当于对象添加了一个自己的普通属性。所以类的属性只能通过类名.nationality来修改。
  •   方法
      方法也是公有的,要注意理解。之所以要用对象的引用调用,因为定义时要通过self传递参数。
def shot2(self):  
    print("run my own shot method, self.name
  
r1.shot = shot2
  
r1.shot(r1)
  
r2.shot()
  
# 注意,r1对象shot方法对应的方法已经被外部定义的shot2方法替换,并且需要手动传递参数
  
# r2则使用的时原来的参数

  •   析构方法
      __del__(self),对象的引用被清理时会被自动调用,相当于“回调方法”在自定义对象被清理时,手动清理需要清理的变量。
  关于继承机制
  继承机制能够让子类或派生类在使用父类(基类)的功能,并且在无需编写原来功能代码的情况下对这些功能进行扩展。继承机制的实现有以下三种方式:

  •   单继承
      先继承再重写
class Person(object):  
    person_count = 0
  
    def __init__(self, name, age, sex):
  
        self.name = name
  
        self.age = age
  
        self.sex = sex
  

  
    def talk(self):
  
        print("Person is talking.")
  

  
    def inroll(self):
  
        # 类的计数器要使用类名调用
  
        Person.person_count += 1
  

  
    def tell(self):
  
        print("%s info" % self.name)
  
        for k,v in self.__dict__.items():
  
            print(k, v)
  

  
class BlackPerson(Person):
  
    def __init__(self, name, age, sex, strength):
  
        # 这里先继承了父类,然后重写了方法,并调用了父类的方法
  
        #  Person.__init__(self, name, age, sex)  # 经典类写法
  

  
        # 新式类写法,注意self参数的位置,以及理解调用机制
  
        super(Person, self).__init__(name, age, sex)
  
        self.strength = strength
  
        print(self.name, self,age, self, sex)
  

  
    def talk(self):
  
        # 同名方法,子类会覆盖父类的方法
  
        print("Black person is talking")
  

  
    def walk(self):
  
        # 子类对父类的拓展
  
        print("Black is walking.")

  •   多继承
  再Python2和Python3里类的寻找路径是有区别的,Python2是深度优先(是否区分经典和新式?),Python3是广度优先。
# 此代码在windows下Python3环境运行  
# 无论O是新式或经典写法,查询路径都是广度优先,很可能Python3内部实现已经全部归于新式类
  
class O(object):
  
    def __init__(self):
  
        print("init O")
  
        self.n = "O"
  

  
class A(O):
  
    pass
  
    # def __init__(self):
  
    #     print("init A")
  
    #     self.n = "A"
  

  
class B(O):
  
    # pass
  
    def __init__(self):
  
        print("init B")
  
        self.n = "B"
  

  
class C(A, B):
  
    pass
  

  
cc = C()
  
print(cc.n)
  但是利用在线解释器,使用Python2.7环境下会有区别,如图:
DSC0000.png

DSC0001.png

  可以看出区别,Python2.7环境下,新式类广度优先,经典类深度优先(注意O的写法)
  广度优先和深度优先的临界点
DSC0002.png

  只有查找到A0时才会判断使用深度优先还是广度优先,如果再A0时查找O则是深度优先,如果去查找B1则是广度优先!

  •   组合
  关于多态
  接口重用,通俗讲,就是通过父类调用子类的方法,体现出不同的形态。
class Animal(object):  
    def talk(self):
  
        raise NotImplementedError("未实现该方法,报错")
  

  
    def real_talk(self):
  
        print(self.talk())
  

  
class Cat(Animal):
  
    def talk(self):
  
        return "Meow!"
  

  
class Dog(Animal):
  
    def talk(self):
  
        return "Woof,Woof!"
  

  
c = Cat()
  
d = Dog()
  
c.real_talk()
  
d.real_talk()
  补充
  类,对象的关系
  ssh应用案例:
# 整个过程还是抽象,抽象,抽象  
class SSH:
  
    def __init__(self, host, port, pwd, username):
  
        self.host = host
  
        self.port = port
  
        self.qwd = pwd
  
        self.username = username
  

  
    def connection(self):
  
        # 创建链接
  
        #  self.conn = 链接对象()
  
        pass
  

  
    def close(self):
  
        # 关闭链接
  
        pass
  

  
    def upload(self):
  
        pass
  

  
    def com(self):
  
        pass
  

  
obj = SSH()
  函数保存在类里,字段保存在对象里。
  静态属性(共有属性)
  封装的理解:
  类封装了字段名和方法,“抽象”是封装的方法论;
  对象封装了字段的值,也就是类的实体;
  类方法寻找的顺序,要注意F2的a1方法里调用self.a2(),self.a2()寻找的起点仍然是F3
class F1:  
    def __init__(self):
  
        print("F1")
  

  
    def a1(self):
  
        print("F1a1")
  

  
    def a2(self):
  
        print("F1a2")
  

  
class F2(F1):
  
    def __init__(self):
  
        print("F2")
  

  
    def a1(self):
  
        self.a2()
  
        print("F2a1")
  

  
    def a2(self):
  
        print("F2a2")
  

  
class F3(F2):
  
    def __init__(self):
  
        print("F3")
  

  
    def a2(self):
  
        print("F3a2")
  

  
obj = F3()
  
obj.a1() # F3a2 F2a1
  静态方法 @staticmethod
  保存在类里
class F1:  
    def __init__(self):
  
        print("F1")
  

  
    @staticmethod
  
    def a1(): # 可以没有self参数,也可以设定任意参数
  
        print("F1a1")
  

  
F1.a1() # 通过类来访问
  Python是否有“静态变量”?
  Python是动态语言,它的类严格讲没有静态变量,不过从特性上来讲,类变量可以称为“静态变量”

  •   子类调用父类构造方法
# 两种方法可以实现  
class A:
  
    def __init__(self):
  
        self.hungry = True
  

  
class B:
  
    def __init__(self):
  
        A.__init__(self) # 方法一,调用父类的未绑定构造方法
  
        # super(A, self).__init__()  # 方法二,super函数返回的引用相当于父类对象的引用,可以直接调用。
  
        self.sound = "Squawk!"
  两种方法均可以调用,通过super函数调用的写法是新式类的写法,而利用父类的未绑定构造方法并传入self引用的调用方法是“传统阵营”的写法。所以使用super更被推荐。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-552123-1-1.html 上篇帖子: Python面试问题(必看) 下篇帖子: Python 学习日记第二篇 -- 列表,元组
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表