zoukankan      html  css  js  c++  java
  • 学习python5面向

    类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用

    • 面向过程:根据业务逻辑从上到下写代码
    • 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程
    • 面向对象(object-oriented ;简称: OO) 至今还没有统一的概念 我这里把它定义为: 按人们 认识客观世界的系统思维方式,采用基于对象(实体) 的概念建立模型,模拟客观世界分析、设 计、实现软件的办法。

      面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法。 这种方法把软件系统中相近相似的操作逻辑和操作 应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。

    创建对象的格式为:

    对象名 = 类名()

    self代表类的实例,而非类

    类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。

    self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。

    self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的:

    class Test:
       def prt(runoob):
        print(runoob)
        print(runoob.__class__)
    t = Test()
    t.prt()
    在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数
    #类定义
    class people:
    #定义基本属性
    name = '' age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0#两个下划线
    #定义构造方法
    def __init__(self,n,a,w):
      self.name = n
      self.age = a
      self.__weight = w
      def speak(self):
         print("%s 说: 我 %d 岁。" %(self.name,self.age))
    # 实例化类
    p = people('runoob',10,30)
    p.speak()
     

    执行以上程序输出结果为:

    runoob 说:  10 岁。
    • 第一次使用BMW.color = '黑色'表示给BMW这个对象添加属性,如果后面再次出现BMW.color = xxx表示对属性进行修改
    • BMW是一个对象,它拥有属性(数据)和方法(函数)
    • 当创建一个对象时,就是用一个模子,来制造一个实物
    import time
    class Animal(object):

    # 初始化方法
    # 创建完对象后会自动被调用
    def __init__(self, name):
    print('__init__方法被调用')
    self.__name = name


    # 析构方法
    # 当对象被删除时,会自动被调用
    def __del__(self):
    print("__del__方法被调用")
    print("%s对象马上被干掉了..."%self.__name)

    # 创建对象
    dog = Animal("哈皮狗")

    # 删除对象
    del dog


    cat = Animal("波斯猫")
    cat2 = cat
    cat3 = cat

    print("---马上 删除cat对象")
    del cat
    print("---马上 删除cat2对象")
    del cat2
    print("---马上 删除cat3对象")
    del cat3

    print("程序2秒钟后结束")
    time.sleep(2)
    # 创建对象后,python解释器默认调用__init__()方法;
    # 当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法


    #!/usr/bin/python
    # encoding=utf-8
    class SweetPotato:
    "这是烤地瓜的类"

    #定义初始化方法
    def __init__(self):
    self.cookedLevel = 0
    self.cookedString = "生的"
    self.condiments = []

    #定制print时的显示内容
    def __str__(self):
    msg = self.cookedString + " 地瓜"
    if len(self.condiments) > 0:
    msg = msg + "("

    for temp in self.condiments:
    msg = msg + temp + ", "
    msg = msg.strip(", ")

    msg = msg + ")"
    return msg

    #烤地瓜方法
    def cook(self, time):
    self.cookedLevel += time
    if self.cookedLevel > 8:
    self.cookedString = "烤成灰了"
    elif self.cookedLevel > 5:
    self.cookedString = "烤好了"
    elif self.cookedLevel > 3:
    self.cookedString = "半生不熟"
    else:
    self.cookedString = "生的"

    #添加配料
    def addCondiments(self, condiments):
    self.condiments.append(condiments)

    # 用来进行测试
    mySweetPotato = SweetPotato()
    print("------有了一个地瓜,还没有烤-----")
    print(mySweetPotato.cookedLevel)
    print(mySweetPotato.cookedString)
    print(mySweetPotato.condiments)
    print("------接下来要进行烤地瓜了-----")
    print("------地瓜经烤了4分钟-----")
    mySweetPotato.cook(4) #烤4分钟
    print(mySweetPotato)
    print("------地瓜又经烤了3分钟-----")
    mySweetPotato.cook(3) #又烤了3分钟
    print(mySweetPotato)
    print("------接下来要添加配料-番茄酱------")
    mySweetPotato.addCondiments("番茄酱")
    print(mySweetPotato)
    print("------地瓜又经烤了5分钟-----")
    mySweetPotato.cook(5) #又烤了5分钟
    print(mySweetPotato)
    print("------接下来要添加配料-芥末酱------")
    mySweetPotato.addCondiments("芥末酱")
    print(mySweetPotato)
    • 如果直接修改属性,烤地瓜至少需要修改2部分,即修改cookedLevel和cookedString。而使用方法来修改时,只需要调用一次即可完成
    • 如果直接访问属性,可能会出现一些数据设置错误的情况产生例如cookedLevel=-3。这会使地瓜比以前还生,当然了这也没有任何意义,通过使用方法来进行修改,就可以在方法中进行数据合法性的检查


    class People(object):

    def __init__(self, name):
    self.__name = name

    def getName(self):
    return self.__name

    def setName(self, newName):
    if len(newName) >= 5:
    self.__name = newName
    else:
    print("error:名字长度需要大于或者等于5")

    xiaoming = People("dongGe")

    xiaoming.setName("wanger")
    print(xiaoming.getName())

    xiaoming.setName("lisi")
    print(xiaoming.getName())
    # • Python中没有像C++中public和private这些关键字来区别公有属性和私有属性
    # • 它是以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。
     
    #!/usr/bin/python
    # encoding=utf-8
    #定义一个home类
    class Home:

    def __init__(self, area):
    self.area = area #房间剩余的可用面积
    #self.light = 'on' #灯默认是亮的
    self.containsItem = []

    def __str__(self):
    msg = "当前房间可用面积为:" + str(self.area)
    if len(self.containsItem) > 0:
    msg = msg + " 容纳的物品有: "
    for temp in self.containsItem:
    msg = msg + temp.getName() + ", "
    msg = msg.strip(", ")
    return msg

    #容纳物品
    def accommodateItem(self,item):
    #如果可用面积大于物品的占用面积
    needArea = item.getUsedArea()
    if self.area > needArea:
    self.containsItem.append(item)
    self.area -= needArea
    print("ok:已经存放到房间中")
    else:
    print("err:房间可用面积为:%d,但是当前要存放的物品需要的面积为%d"%(self.area, needArea))


    #定义bed类
    class Bed:

    def __init__(self,area,name = '床'):
    self.name = name
    self.area = area

    def __str__(self):
    msg = '床的面积为:' + str(self.area)
    return msg

    #获取床的占用面积
    def getUsedArea(self):
    return self.area

    def getName(self):
    return self.name


    #创建一个新家对象
    newHome = Home(100)#100平米
    print(newHome)

    #创建一个床对象
    newBed = Bed(20)
    print(newBed)

    #把床安放到家里
    newHome.accommodateItem(newBed)
    print(newHome)

    #创建一个床对象
    newBed2 = Bed(30,'席梦思')
    print(newBed2)

    #把床安放到家里
    newHome.accommodateItem(newBed2)
    print(newHome)


    继承
    class DerivedClassName(BaseClassName1):

    需要注意圆括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内

    #单继承示例

    class student(people):

      grade = ''

      def __init__(self,n,a,w,g):

       #调用父类的构函

      people.__init__(self,n,a,w)

      self.grade = g

       #覆写父类的方法

      def speak(self):

        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

    s = student('ken',10,60,3)

    s.speak()

    执行以上程序输出结果为:

    ken 说:  10 岁了,我在读 3 年级
    多继承
    #另一个类,多重继承之前的准备
    class speaker():
      topic = ''
       name = ''
      def __init__(self,n,t):
        self.name = n
        self.topic = t
      def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
    #多重继承
    class sample(speaker,student):
       a =''
      def __init__(self,n,a,w,g,t):
         student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)
    test = sample("Tim",25,80,4,"Python")
    test.speak() #方法名同,默认调用的是在括号中排前地父类的方法
    
    

    执行以上程序输出结果为:

    
    
    我叫 Tim,我是一个演说家,我演讲的主题是 Python
    #coding=utf-8
    class base(object):
    def test(self):
    print('----base test----')
    class A(base):
    def test(self):
    print('----A test----')

    # 定义一个父类
    class B(base):
    def test(self):
    print('----B test----')

    # 定义一个子类,继承自A、B
    class C(A,B):
    pass


    obj_C = C()
    obj_C.test()

    print(C.__mro__) #可以查看C类的对象搜索方法时的先后顺序
    # • python中是可以多继承的
    # • 父类中的方法、属性,子类会继承
    
    

    方法重写

    
    

    如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法

    c.myMethod() # 子类调用重写方法

    super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法

    #coding=utf-8
    class Cat(object):
    def sayHello(self):
    print("halou-----1")


    class Bosi(Cat):

    def sayHello(self):
    print("halou-----2")

    bosi = Bosi()

    bosi.sayHello()
    # 所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
    #coding=utf-8
    class Cat(object):
    def __init__(self,name):
    self.name = name
    self.color = 'yellow'


    class Bosi(Cat):

    def __init__(self,name):
    # 调用父类的__init__方法1(python2)
    #Cat.__init__(self,name)
    # 调用父类的__init__方法2
    #super(Bosi,self).__init__(name)
    # 调用父类的__init__方法3
    super().__init__(name)

    def getName(self):
    return self.name

    bosi = Bosi('xiaohua')

    print(bosi.name)
    print(bosi.color)
    #调用父类方法

    多态

    多态的概念是应用于JavaC#这一类强类型语言中,而Python崇尚鸭子类型

    所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态

    类属性与方法

    类的私有属性

    __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

    类的方法

    在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。

    self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。

    类的私有方法

    __private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods

    静态方法和类方法

     

    1. 类方法

    是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。

     

     

    # 类方法还有一个用途就是可以对类属性进行修改:
    class People(object):
    country = 'china'

    #类方法,用classmethod来进行修饰
    @classmethod
    def getCountry(cls):
    return cls.country

    @classmethod
    def setCountry(cls,country):
    cls.country = country


    p = People()
    print (p.getCountry()) #可以用过实例对象引用
    print (People.getCountry()) #可以通过类对象引用

    p.setCountry('japan')

    print (p.getCountry())
    print (People.getCountry())
     class People(object):
        country = 'china'

    @staticmethod
    #静态方法
    def getCountry():
    return People.country


    print (People.getCountry())
    #需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数
    # 总结
    # 从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,
    # 那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,
    # 那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不
    # 过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数
    # ,因此在静态方法中引用类属性的话,必须通过类对象来引用
    #coding=utf-8
    classbase(object):
        deftest(self):
            print('----base test----')
    classA(base):
        deftest(self):
            print('----A test----')
     
    # 定义一个父类
    classB(base):
        deftest(self):
            print('----B test----')
     
    # 定义一个子类,继承自AB
    classC(A,B):
        pass
     
     
    obj_C = C()
    obj_C.test()
     
    print(C.__mro__) #可以查看C类的对象搜索方法时的先后顺序
  • 相关阅读:
    rsync+crontab 企业实战 全量备份
    添加共享文件盘,切换用户访问共享
    一天电你千百回,这样做远离静电你造么~
    Network Password Recovery工具查看windows凭据密码
    su 和su
    运维面试 怎么实现程序自启
    在tomcat中配置域名的方法
    使用windows update blocker工具关闭windows系统自动更新
    CVM 母机透传,什么是透传模块?为什么要透传?
    硬盘接口类型
  • 原文地址:https://www.cnblogs.com/pursue339/p/10413178.html
Copyright © 2011-2022 走看看