python 类和对象的详细分析

前言

使用python做深度学习框架的代码或者软件开发的时候,默认都会当成习惯使用,但一问三不知。

对此本篇文章主要是做一个深入剖析,方便自身以及各位的学习。

1. 概念

  • :代表事物或者某一特征,比较抽象。比如人、学生等。(常用的类名采用驼峰规则,比如FirstName)
  • 对象:由类创建出的对象,可赋予其属性和方法。比如学生类中创建小明,小明为对象,其属性可以为姓名、年龄,方法可以是学习等动作。

两者之间的关系:

  • 类只有一个,对象可以多个。
  • 不同对象之间的属性可能不同。

2. 代码讲解

类和对象层层相扣,先有类才有对象

第一步创建类:

class Person:   
	# 类属性
    name='研究僧'  
    age=18       
    
   # 实例方法
    def __init__(self):
        self.name='研究僧'   
    def eat(self):
        print("大口吃饭")
    def shit(self):  
        print('快速拉屎')

第二步创建对象

大致格式为:对象名 = 类名()


#创建对象
person = Person()   

# 调用对象中的方法
person.shit()   

# 访问类属性
print(person.name)  

以上代码使用类名()创建对象后,会自动执行如下操作:

  1. 内存中分配空间来创建对象。
  2. 为对象设置属性初始值(_ init _()初始化方法),该方法本身是对象的内置方法,会自动调用:(self.属性 = 形参

常把_ init _()成为构造方法,而且返回值一定是None,一般在初始化属性的时候才需要重写该方法,而不是实例化对象时第一个调用的方法。


对于以上代码的注意事项:
(在类的内部,通过self来标识自身对象,self类似C++中的指针,标识自身)

  • 类方法中必须包含参数self,self必须是第一个参数,比如def eat(self)
  • 类中的属性分为两种,分别为类属性和实例属性
    类属性:定义在类里方法外
    实例属性:方法里,可通过self.变量

在方法内,可通过self访问对象属性,或者调用其他对象方法
一个类中可以有多个实例属性

class Person:   
	name='研究僧'  

    def __init__(self):
        self.name = " 码农"   

    # 一个类里面可以有多个实例属性
    def show(self):
        print(Person.show)

3. 拓展

3.1 公有/私有属性

对于其他的编程语言,都有public或者private关键字,默认都是公开的,通过(.)访问即可:

class Person:   
	name='研究僧' 

person = Person()   

# 输出 研究僧
person.name

为了将以上改为私有,通过name mangling技术,只需要在私有变量或函数名加上**“_ _”两个下划线**,访问时,需要从内部进行访问。

class Person:   
	def __init__(self,name):
        self.__name = name
    def getName(self):
    	print(self.__name)
person = Person("码农研究僧")   

# 出现错误,因此此为私有变量
person.__name

# 输出 码农研究僧
person.getName()

但python的私有变量其实是可以外部调用(徒有虚名),只需通过_类名_ _变量名即可访问

class Person:   
	__name = "码农研究僧"

person = Person()   

# 出现错误,因此此为私有变量
person.__name

# 输出 码农研究僧
person._Person__name

3.2 单继承

继承类似java中的继承,即相同属性和方法可以自动继承,比如爷爷、爸爸、儿子等,主要的语法为:class 类名(继承的类):

class Parent:   
	def show(self):
    	print("Father")

class Child(Parent):
	pass

p = Parent()
# 输出 Father
p.show()

c = Child()
# 输出 Father
c.show()

如果子类与父类同方法属性,则自动覆盖父类的方法或属性:

class Parent:   
	def show(self):
    	print("Father")

class Child(Parent):
	def show(self):
    	print("Son")

c = Child()
# 输出 Son
c.show()

3.3 多继承

class Parent1:   
	def show1(self):
    	print("Father1")
    	
class Parent2:   
	def show2(self):
    	print("Father2")

class P(Parent1,Parent2):
	pass

p = P()

# 输出Father1
p.show()
# 输出Father2
p.show()

以上是多继承的思想,但代码会混乱,尽量避免避开,不推广

3.4 super

类似java,super代表父类

前面讲过如果子类的某些方法与父类方法不一致,无法覆盖,就会出错,为了引入super函数,先讲解如下代码:

import random as r
     
class Aa:
	def __init__(self):
		# 随机0到10
		self.x = r.randint(0, 10)

	def decrease(self):
        self.x -= 1
        print(self.x)
         
# 继承aa
class Bb(Aa):
    pass
    
# 继承aa
class Cc(Aa):
    pass

# 继承aa
class Dd(Aa):
    def __init__(self):
        self.name = "码农研究僧"

    def show(self):
        print(self.name)

此时如果输出:

aa = Aa()
# 可执行
aa.decrease()

dd = Dd()
# 可执行
dd.show()
# 不可执行
dd.decrease()

至于dd.decrease()不可执行,是因为在dd中没有x的属性,所以调用decrease方法会出错,解决如下问题其中之一是用super函数,另外一个方法是调用未绑定父类的方法。

super函数

# 继承aa
class Dd(Aa):
    def __init__(self):
    	super().__init()
        self.name = "码农研究僧"

dd = Dd()
# 可执行
dd.show()
# 可执行
dd.decrease()

另外一种方法:(调用未绑定父类的方法)

# 继承aa
class Dd(Aa):
    def __init__(self):
    	Aa().__init(self)
        self.name = "码农研究僧"

dd = Dd()
# 可执行
dd.show()
# 可执行
dd.decrease()

上述的self并非是父类的Aa实例对象,而是子类Dd的实例对象,此处并不需要绑定父类实例对象,只需要使用子类实例对象即可。

猜你喜欢

转载自blog.csdn.net/weixin_47872288/article/details/133367729
今日推荐