首页 > 编程语言 >Python语法学习五之面向对象

Python语法学习五之面向对象

时间:2024-04-03 17:22:52浏览次数:26  
标签:__ Python self 语法 面向对象 实例 print def 属性

一、面向对象1

1-1、定义类

语法:

class 类名:
    方法列表
# 定义类
class Car:

    def getCarInfo(self):
        # 定义属性,和Java等语言差别很大。
        print('车轮子个数:%d, 颜色%s' % (self.wheelNum, self.color))

    def move(self):
        print("车正在移动...")

    def toot(self):
        print("车在鸣笛...嘟嘟..")
1-2、创建对象
# 创建对象
BMW = Car()
BMW.color = '黑色'
BMW.wheelNum = 4

BMW.getCarInfo()
BMW.move()
BMW.toot()

print(BMW.color)
print(BMW.wheelNum)

注意:

  • BMW = Car(),这样就产生了一个Car的实例对象,此时也可以通过实例对象BMW来访问属性或者方法。
  • 第一次使用BMW.color = '黑色'表示给BMW这个对象添加属性,如果后面再次出现BMW.color = xxx表示对属性进行修改
  • BMW是一个对象,它拥有属性(数据)和方法(函数)
1-3、魔法函数
  • 在python中方法名如果是_ _ xxxx _ _(self)的,那么就有特殊的功能,因此叫做“魔法”方法
  • 当使用print输出对象的时候,只要自己定义了 _ _ str _ _(self)方法,那么就会打印从在这个方法中return的数据
1-3-1、构造方法: _ _ init _ _(self)
# 定义类
class Car:

    # 构造方法
    def __init__(self):
        print "__init__方法"
        self.wheelNum = 8
        self.color = '蓝色'

    def getCarInfo(self):
        # 定义属性,和Java等语言差别很大。
        print('车轮子个数:%d, 颜色%s' % (self.wheelNum, self.color))

    # 方法
    def move(self):
        print("车正在移动...")

    def toot(self):
        print("车在鸣笛...嘟嘟..")


# 创建对象
BMW = Car()

BMW.getCarInfo()

注意:

  • init()方法,在创建一个对象时默认被调用,不需要手动调用

  • init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中出了self作为第一个形参外还需要2个形参,例如__init__(self,x,y)

  • init(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去

1-3-2、_ _ str_ _(self)方法
# 定义类
class Car:

    # 构造函数
    def __init__(self, newWheelNum, newColor):
        self.wheelNum = newWheelNum
        self.color = newColor

    # 类似Java中的toString()方法
    def __str__(self):
        msg = "嘿。。。我的颜色是" + self.color + "我有" + str(self.wheelNum) + "个轮胎..."
        return msg

    def move(self):
        print('车在跑,目标:夏威夷')


BMW = Car(4, "白色")
print(BMW)
1-4、self

魔法函数中的self参数

  • 所谓的self,可以理解为自己
  • 可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思
  • 某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可

二、面向对象2

2-1、私有属性

如果有一个对象,当需要对其进行修改属性时,有2种方法

    对象名.属性名 = 数据 ---->直接修改
    对象名.方法名() ---->间接修改

为了更好的保存属性安全,即不能随意修改,一般的处理方式为

    将属性定义为私有属性
    添加一个可以调用的方法,供调用
class People(object):

    def __init__(self, name):
        # 声明私有属性,类似Java中的private
        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")
print(xiaoming.__name)
# 执行报错
2-2、_ _ del _ _(self)方法
  • 创建对象后,python解释器默认调用_ _ init _ _()方法;
  • 当删除一个对象时,python解释器也会默认调用一个方法,这个方法为 _ _ del _ _()方法。当对象被销毁,例如内存被释放或程序结束时,会自动被调用,类似OC的dealloc()方法。
  • del 对象:类似OC的release()方法,让引用计数 -1,此时引用计数为1
import time


class Animal(object):

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

    # 析构方法
    # 当对象被销毁,例如内存被释放或程序结束时,会自动被调用,类似OC的dealloc()方法
    def __del__(self):
        print("%s对象被干掉了..." % self.__name)

    def move(self):
        print("%s对象在移动" % self.__name)


# 引用计数为1
cat = Animal("波斯猫")
# 引用计数为2
cat1 = cat

# 类似OC的release()方法,让引用计数 -1,此时引用计数为1
del cat

# 调用完del方法后,cat指针指向的对象引用计数 -1,cat指针被释放,再次使用会报错
# del cat
# cat.move()
# 报错,cat指针已经被销毁了

# 类似OC的release()方法,让引用计数 -1,此时引用计数为0,对象释放,会在此时调用_ _ del _ _方法。如果注释下面代码,则cat对象会在程序结束后释放。
del cat1

print("程序2秒钟后结束,所以内存中的对象都会被释放")
time.sleep(2)
2-3、单继承
  • 子类在继承的时候,在定义类时,小括号()中为父类的名字
  • 父类的属性、方法,会被继承给子类
  • 私有的属性,不能通过对象直接访问,但是可以通过方法访问
  • 私有的方法,不能通过对象直接访问
  • 私有的属性、方法,不会被子类继承,也不能被访问
  • 一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用
class Animal(object):
    def __init__(self, name="动物", color="白色"):
        self.__name = name
        self.color = color

    def __test(self):
        print self.__name
        print self.color

    def test(self):
        print self.__name
        print self.color


class Dog(Animal):

    def dogTest1(self):
        print self.__name  # 不能访问到父类的私有属性
        print self.color

    def dogTest2(self):
        self.__test()  # 不能访问父类中的私有方法
        self.test()


A = Animal()
print(A.__name)  # 程序出现异常,不能访问私有属性
print(A.color)

A.__test()  # 程序出现异常,不能访问私有方法
A.test()

D = Dog(name="旺财", color="黄色")
D.dogTest1()
D.dogTest2()
2-4、多继承
  • Python和C++一样支持多继承
# 定义一个父类
class A:
    def printA(self):
        print('----A----')


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


# 定义一个子类,继承自A、B
class C(A, B):
    def printC(self):
        print('----C----')


obj_C = C()
obj_C.printA()
obj_C.printB()
obj_C.printC()
  • 有多个父类的同名方法时,调用同名方法时,方法的调用顺序和多继承的顺序有关系
  • pass关键字来进行占位,让代码不要报错先能正常运行
#! /usr/bin/env 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关键字来进行占位,让代码不要报错先能正常运行
    pass

    # def test(self):
    #     print('----C test----')


obj_C = C()
obj_C.test()

print(C.__mro__)  # 可以查看C类的对象搜索方法时的先后顺序。注意和继承的父类顺序有关系
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.base'>, <type 'object'>)
2-5、重写父类方法与调用父类方法
2-5-1、重写父类方法

所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法。

class Cat(object):
    def sayHello(self):
        print("Cat--sayHello")


class Bosi(Cat):

    def sayHello(self):
        print("Bosi--sayHello")


bosi = Bosi()

bosi.sayHello()
# Bosi--sayHello
2-5-2、调用父类的方法

*方法1(Python2)

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

示例

# 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(python2)
        super(Bosi, self).__init__(name)

        # 调用父类的__init__方法3(python3)
        # super().__init__(name)

        self.color = 'green'


def getName(self):
    return self.name


bosi = Bosi('xiaohua')

print(bosi.name)
print(bosi.color)
2-6、多态

多态的概念是应用于Java和OC这一类强类型语言中,而Python崇尚“鸭子类型”。所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态。简单来说就是父类指针指向子类对象。

class F1(object):
    def show(self):
        print 'F1.show'

class S1(F1):

    def show(self):
        print 'S1.show'

class S2(F1):

    def show(self):
        print 'S2.show'

def Func(obj):
    print obj.show()

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj)
2-7、类属性和实例属性
  • 实例属性:也就是对象属性,某一个对象所拥有的属性,通过对象可以访问到各自的实例属性。
  • 类属性:顾名思义就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,和Java/C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象或者实例对象访问。
2-7-1、类属性
class People(object):
    name = 'Tom'  #公有的类属性
    __age = 12     #私有的类属性

p = People()

print(p.name)           #正确,可以通过实例对象来访问类属性。
print(People.name)      #正确,可以通过类对象来访问类属性。

print(p.__age)            #错误,不能在类外通过实例对象访问私有的类属性
print(People.__age)        #错误,不能在类外通过类对象访问私有的类属性
2-7-2、实例属性(对象属性)
class People(object):
    address = '山东' #类属性

    def __init__(self):
        self.name = 'xiaowang' #实例属性
        self.age = 20 #实例属性

p = People()
p.age =12 #实例属性

print(p.address) #正确,可以通过实例对象访问类属性

print(p.name)    #正确,可以通过实例对象访问自己的实例属性
print(p.age)     #正确,可以通过实例对象访问自己的实例属性

print(People.address) #正确,可以通过类对象访问类属性

print(People.name)    #错误,不能通过类对象访问实例属性
print(People.age)     #错误,不能通过类对象访问实例属性
2-7-3、通过实例(对象)去修改类属性的坑!!!
  • 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。看下面例子:
class People(object):
    country = 'china'  # 类属性

print("1" + People.country)

p = People()
print("2" + p.country)

p.country = 'japan'  # 一定要注意,这句代码相当于是给p对象添加一个实例属性!!!类似下面
p.name = 'cehae' #给p对象添加一个name实例属性

print("3" + p.country)  # 实例属性会屏蔽掉同名的类属性,此时访问的是上面添加的country实例属性

print("4" + People.country)
print("5" + p.country)

del p.country  # 删除实例属性
print("6" + p.country)  # 删除实例属性后,此时访问的是类属性

图片.png

2-8、类方法和静态方法
2-8-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()  # 可以用实例对象来调用类方法
# china
print People.getCountry()  # 可以用类对象来调用类方法
# china
p.setCountry('japan')  # 可以用实例对象来调用类方法
People.setCountry('us')  # 可以用类对象来调用类方法

print p.getCountry()  # 可以用实例对象来调用类方法
# us
print People.getCountry()  # 可以用类对象来调用类方法
# us
2-8-2、静态方法

静态方法是指类中无需实例参与即可调用的方法(不需要self参数),在调用过程中,无需将类实例化,直接在类之后使用.号运算符调用方法。

通常情况下,静态方法使用@staticmethod装饰器来声明。

示例代码:

class ClassA(object):

    @staticmethod
    def func_a():
        print('Hello Python')

if __name__ == '__main__':
    ClassA.func_a()
    # 也可以使用实例调用,但是不会将实例作为参数传入静态方法
    ca = ClassA()
    ca.func_a()

这里需要注意的是,在Python 2 中,如果一个类的方法不需要self参数,必须声明为静态方法,即加上@staticmethod装饰器,从而不带实例调用它。

而在Python 3中,如果一个类的方法不需要self参数,不再需要声明为静态方法,但是这样的话只能通过类去调用这个方法,如果使用实例调用这个方法会引发异常。

class ClassA(object):


    def func_a():
        print('Hello Python')

if __name__ == '__main__':
    ClassA.func_a()
    # 以下使用实例调用会引发异常
    ca = ClassA()
    ca.func_a()

异常信息:
func_a() takes 0 positional arguments but 1 was given
因为func_a没有声明为静态方法,类实例在调用func_a时,会隐式地将self参数传入func_a,而func_a本身不接受任何参数,从而引发异常。
2-8-3、静态方法/类方法/实例方法的总结

Python静态方法/类方法/实例方法的总结1
Python静态方法/类方法/实例方法的总结2

图片.png

  • 1.实例方法:第一个参数强制为实例对象,可以通过这个实例对象访问实例属性,可以通过实例对象的_ _ class _ _属性访问类属性。只能使用实例对象调用实例方法。

  • 2.类方法:类方法的第一个参数强制为类对象,可以通过这个类对象访问类属性,由于没有传入实例对象,不能访问实例属性。可以使用类对象和实例对象来调用类方法。

  • 3.静态方法:没有默认的第一个参数,其实跟类没什么关系,只是绑定在类命名空间下的函数而已。可以使用类对象和实例对象来调用静态方法。

  • 4.同时出现三者同名的方法,调用时以最后声明的为准!!!

class People(object):
    country = 'china'

    # 实例方法,Python2中实例方法必须带有self参数
    def getCountry(self):
        print "实例方法"
        return People.country

    # 静态方法,用staticmethod来进行修饰
    @staticmethod
    def getCountry():
        print "静态方法"
        return People.country

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


p = People()
print p.getCountry()
print People.getCountry()
2-9、延伸:Java/OC中的类方法/实例方法,类属性/对象属性
  • Java/OC中的静态方法就是类方法,静态属性就是类属性。
  • Java/OC中的实例方法也称对象方法。

Java类方法和实例方法
OC类方法和实例方法
OC静态变量

标签:__,Python,self,语法,面向对象,实例,print,def,属性
From: https://www.cnblogs.com/adongdong2024/p/18113145

相关文章

  • 自学python能干些什么副业,自学python能做什么工作
    前言大家好,小编来为大家解答以下问题,有人自学python成功赚钱了吗,自学python能干些什么副业,现在让我们一起来看看吧!自学Python找工作主要看自己的学习能力,自学能力很强学完并精通当然可以工作,不过对于大多数人而言一般都挺难,学习不成系统,遇到问题没人解决很容易放弃半途而......
  • Python免费下载安装全流程(Python 最新版本),新手小白必看!
    前言今天换了新的电脑,需要重新安装python和PyCharm,就简单的写个教程吧~一、Python下载1、进入Python官网官网地址:https://www.python.org2、点击【Downloads】展开后点击【Windows】跳转到下载python版本页面,选择"StableReleases"稳定版本,我下载的是Python3.10.10版......
  • Python就业前景如何?薪资待遇怎么样?
    前言Python作为一种高级编程语言,已经在多个领域得到了广泛的应用,包括数据分析、人工智能、Web开发等。随着技术的不断发展和应用领域的不断扩展,Python的就业前景也越来越广阔。首先,Python在数据分析领域的应用非常广泛。随着大数据时代的到来,数据分析已经成为了许多企业......
  • 学了python可以做什么兼职,学python真的能做兼职吗??
    前言学好Python可以做什么兼职1、爬虫首先,除了Python的语法基础的之外的必修课就是web开发和爬虫的内容了。如果是想依靠这两个方向来赚钱的话,就必须要清楚的知道开发什么或者爬什么数据才能赚钱。如果你都不知道的话,你可以开个网店,或者去猪八戒做服务的外包。不管是web......
  • vs2022 开始自己的第一个Python程序
    这是针对于vs2022安装和使用教程(详细)创建Python项目的简单示例,旨在示范从项目搭建到程序运行的简单流程,代码就是打印HelloWorld,适合初次使用vs2022的用户~ 1.以Python为例,下拉到Python应用程序,点击后点击右下角的下一步2.改变默认路径,填写项目名称,可勾选将解决方案和项目......
  • Python访问mysql与sqlite3数据库
    在Python中,数据库访问是一个常见的需求,无论是在Web开发还是数据分析中都非常重要。Python提供了多种数据库访问库,使得与不同类型的数据库进行交互变得简单。在这篇博客中,我们将介绍如何使用Python进行数据库访问操作,并提供一些代码示例。Python数据库访问概述Python中的数据......
  • python面向对象的四大支柱:抽象、封装、继承、多态
    1.抽象在面向对象编程中,抽象是指将类的属性和方法捆绑在一起,形成一个整体。抽象类无法实例化,但可以作为其他类的基类或父类。在Python中,我们使用abc模块定义抽象类,其中至少包含一个抽象方法。抽象方法是无法直接调用但可以被子类覆盖的方法。例如,我们可以定义一个Animal类,然......
  • python基础——基础代码每日复习002
    面向对象:#!/usr/bin/python#-*-coding:UTF-8-*-classEmployee:'所有员工的基类'empCount=0def__init__(self,name,salary):self.name=nameself.salary=salaryEmployee.empCount+=1defdisplayCount(sel......
  • python发邮件(文件内容在邮件中展现)
     python3.6#!/usr/bin/envpython#coding=utf-8importsmtplibfromemail.mime.textimportMIMETextfromemail.mime.multipartimportMIMEMultipartfromemail.headerimportHeaderimportdatetimeimporttimemail_host="mail.test.com:465"ma......
  • 03 Python进阶:MySQL
    mysql-connector安装要在Python中使用MySQL数据库,你需要安装MySQL官方提供的MySQLConnector/Python。下面是安装MySQLConnector/Python的步骤:首先,确保你已经安装了Python,如果没有安装,可以在Python官网(https://www.python.org)下载并安装最新版本的Python......