【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法

文章目录

  • 类与对象
  • 类方法与类属性
    • 类方法
    • 类的属性
    • 类方法与类的属性结合使用
    • 类方法传参数
    • 类属性:增加/修改类属性
  • 类的实例化
    • 实例方法与类方法
    • 实例属性和类属性
  • 初始化函数
  • 类的继承
  • 类的重写: __str__()方法
  • @property
  • 私有属性、私有方法


类与对象

【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第1张图片
“类"就像是工厂里模具,以它为模板,选出来成千上万的产品,才是被我们消费购买使用的东西。这些产品就像是"实例对象”。
从模具变成产品,也就是从"类"变成"实例对象"的过程,就叫做实例化


类方法与类属性

类是一个函数包,可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量。

语法:class语句来定义一个类。def自定义一个函数。

类方法

定义:在类中被定义的函数被称为类的方法, 描述的是这个类能做什么。
调用类的方法:类名.函数名()

#创建一个名为“ClassName”的类,类名一般首字母要大写,(): 不能丢 
class ClassName():
#假如定义一个名为“你好”的类,可以写成class Hello():
	def function1():
	# 定义类中的函数1
class ClassA():
	def func1():
		print("我是ClassA的第一个方法!")
	def func2():
		print("我是ClassA的第二个方法!")
	def func3():
		print("我是ClassA的第三个方法!")
		
ClassA.func1()
ClassA.func2()
ClassA.func3()

在这里插入图片描述

类的属性

定义:在类中被定义的变量被称为类的属性
调用类的属性:类名.属性名

class ClassA():
	var1 = 100
	var2 = 200
	var3 = '你好'

print(ClassA.var1)
print(ClassA.var2)
print(ClassA.var3)

在这里插入图片描述

增加/修改类的属性:可以使用类名.变量名在类的外面进行操作。

class ClassA():
	var1 = 100
	var2 = 200
	var3 = '你好'

ClassA.var1 = 99
ClassA.var4 = 'add a var'

print(ClassA.var1)
print(ClassA.var4)

在这里插入图片描述

类方法与类的属性结合使用

方法一:调用类方法与类的属性的结合。

class Robot():
	macaron = 20
	cannele = 15
	cheese_bread = 23
	#以上为类的属性
	
	def welcome_supermarket():
		print("你好,欢迎来到超市的面包区!")
	def pick_one():
		print("我们热销有三款面包哦,欢迎选购~")
	def payment():
		print("收银台在这里,欢迎下次光临~")
	#以上为类的方法
	
#打印类的属性
print(Robot.macaron)
print(Robot.cannele)
print(Robot.cheese_bread)

#调用类的方法	
Robot.welcome_supermarket()
Robot.pick_one()
Robot.payment()

【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第2张图片

方法二:注意 如果类中的函数不需要类中的变量时,就不要用@classmethod、cls、cls. 三处格式,否则也会报错。

class ClassA():
	var1 = 100
	var2 = 200
	
	@classmethod  #类方法,@classmethod声明了func1是类方法,这样子才允许func1使用类属性中的数据。
	def func1(cls):  # class的缩写,如果func1想使用类的属性,就要写上cls作为func1的第一个参数,也就是把这个类作为参数传给自己,这样就能被允许使用类中的数据。
		print(cls.var1)
		print(cls.var2)

ClassA.func1()

在这里插入图片描述

类方法传参数

方法一:将参数放在类的内部,然后类的方法从内部获取参数。

class ClassA():
	num = 1

	@classmethod
	def add_100(cls):
		sum = cls.num + 100
		print("计算结果如下:")
		print(sum)
		
ClassA.add_100()

在这里插入图片描述

方法二:直接 参数=xx

class ClassA():
	def add_100(num):
		sum = num + 100
		print("计算结果如下:")
		print(sum)

num = 1
ClassA.add_100(num)

在这里插入图片描述

方法三:同时使用内部和外部的参数。

举例1:

class ClassA():
	num = 1
	
	@classmethod
	def add_100(cls,para):
		sum = cls.num + 100 + para
		print("计算结果如下:")
		print(sum)

para= 10
ClassA.add_100(para)

在这里插入图片描述

举例2:当类方法要使用多个外部参数,我们要预设几个参数位置。

class ClassA():
	num = 1
	
	@classmethod
	def add_100(cls,para1,para2,para3):
		sum = cls.num + 100 + para1 + para2 + para3
		print("计算结果如下:")
		print(sum)

para1 = 10
para2 = 20
para3 = 30
ClassA.add_100(para1,para2,para3)

在这里插入图片描述

类属性:增加/修改类属性

【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第3张图片

方法一:用 类.变量=xx 直接增加、修改类属性。

class ClassA():

	@classmethod
	def add_class_var(cls):
		print("打印新增的类的属性:" + str(cls.var1))
	
ClassA.var1=100
ClassA.add_class_var()

在这里插入图片描述

方法二:用类方法去增加、修改。

class ClassA():

	@classmethod
	def add_class_var(cls):
		cls.var1 = "hello"
		
ClassA.add_class_var()
print("打印新增的类的属性:" + ClassA.var1)

在这里插入图片描述


类的实例化

实例化基本格式:实例名=类() 为类创建一个实例,然后再使用 实例名.函数() 调用对应的方法。
注意:与直接调用类格式不一样。

class ClassA():
	var1 = 'abc'

	def func(self): #self代表“实例”的意思,编码规范,不是强求。
		print('已经完成了实例化。')
		print('类属性的值是:'+ self.var1)

a=ClassA()
a.func()		

在这里插入图片描述

class Robot():
	macaron = 20
	cannele = 15
	cheese_bread = 23
	
	#以上为类的属性
	def pick_one(self):
		print("我们热销有三款面包哦,欢迎选购~")
		print('马卡龙:' + str(self.macaron))
		print('可丽露:' + str(self.cannele))
		print('芝士面包:' + str(self.cheese_bread))

a=Robot()
a.pick_one()

在这里插入图片描述

注意:
1、实例化后,只要你类中使用了def语句那必须在其后的括号里把第一个位置留给self。
2、当支持实例化时,就不能再直接使用类方法。

实例方法与类方法

重写类方法:类.原始函数=新函数
第一步:在类的外部写一个函数
第二步:把这个新函数的函数赋值给类的原始函数。

class ClassA():
	def func1(self):
		print('我是原始函数')

def func2(self):
	print('我是重写后的新函数')

a = ClassA()
a.func1()

ClassA.func1=func2 
a.func1()

在这里插入图片描述

class Lucky():
	
	def lucky_double(self):
		print('好的,我把你的幸运数字记住了哦,并翻倍66倍还给你' + str(self.lucky_number*66))

def lucky_new_double(self):
	print('好的,我把你的幸运数字记住了哦,并翻倍88倍还给你' + str(self.lucky_number*88))

Lucky.lucky_number = int(input('请输入你的幸运数字'))
a = Lucky()
a.lucky_double()

Lucky.lucky_double=lucky_new_double
a.lucky_double()

在这里插入图片描述

a.lucky_double=lucky_new_double # 尝试重写实例方法,将会报错
a.lucky_double()

【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第4张图片

注意:重写类方法,让实例方法发生变化,但我们不能重写实例方法。

实例属性和类属性

实例属性和类属性:实例后获得类属性,所以实例属性和类属性完全相等。

class ClassA():
	var1 = 100

a = ClassA() #实例化,得到实例对象a
b = ClassA() #实例化,得到实例对象b

print(a.var1)
print(b.var1)

在这里插入图片描述

举例:修改实例属性

class ClassA():
	var1=100

a=ClassA()
b=ClassA()

print('原始属性值')
print(a.var1)
print(b.var1)

ClassA.var1='abc' # 修改类属性
print('修改后属性值')
print(a.var1) # 实例属性同步变化
print(b.var1)

【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第5张图片


初始化函数

初始化函数作用:当你创建一个实例的时候,这个函数就会被调用,初始化当前对象的相关属性,无返回值。上面的代码在执行的实例=类()时,就自动调用__init__(self)函数。

class ClassA():
	def __init__(self):
		print('实例化成功!')
		
a = ClassA() #创建对象,调用__init__()初始属性。		
class ClassA():
	def __init__(self,para1,para2):
		self.var1 = para1  #实例属性
		self.var2 = para2

	def print_var(self):
		print('变量1的值是:' + str(self.var1))
		print('变量2的值是:' + str(self.var2))

class ClassB(ClassA):
	def sum_var(self):
		var_sum = str(self.var1 + self.var2)
		print('所有变量的和是:' + var_sum)
		
b = ClassB(100,200)	
b.print_var()
b.sum_var()

在这里插入图片描述

在一个A类中调用B类,自动调用B类下面的 init(self) 函数。

class A():
    def func_A(self,name1='lily',name2='Jack'):
        names = B(name1,name2)
        return names
        
class B():
    def __init__(self,para1,para2):
        self.var1 = para1
        self.var2 = para2  
        print(self.var1)
        print(self.var2)
    def func_B(self,para3,para4):
        print("在类A中直接调用B类,只会运行__init__初始函数下面的代码,不影响A类中其他函数。")

a = A()
result=a.func_A()

在这里插入图片描述

另一种写法:

class A():
    def func_A(self,name1='lily',name2='Jack'):
        names = B(name1,name2)
        return names
        
class B():
    def __init__(self,para1,para2):
        self.var1 = para1
        self.var2 = para2

    def func_B(self):
        return self.var1
      
    def func_C(self):
        return self.var2
        
a=A()
result=a.func_A()
result.func_B()
result.func_C()

在这里插入图片描述


类的继承

如果新写的类,有许多的代码和旧类相同,又有一部分不同的话 ,可以用继承的方式避免重复写代码。

在python里,我们统一把旧的类称为父类,新写的类称为子类,子类可以在父类基础上改造类方法,所以我们可以说子类继承了父类。

class ClassA():
	def __init__(self,para1,para2):
		self.var1 = para1
		self.var2 = para2

	def print_var(self):
		print('变量1的值是:' + str(self.var1))
		print('变量2的值是:' + str(self.var2))

class ClassB(ClassA):
	def sum_var(self):
		var_sum = str(self.var1 + self.var2)
		print('所有变量的和是:' + var_sum)
		
b=ClassB(100,200)	
b.print_var()
b.sum_var()

在这里插入图片描述


类的重写: str()方法

作用:用于返回一个“对象的描述”,对于内置函数str()经常用于print()方法查看对象的信息。

class A():
	def __init__(self,name,age):
		self.name=name
		self.__age=age
	
p=A('lily',18)
p

# 输出:
# <__main__.A at 0x2b2f3c81640>

重写__str__()方法

class A():
	def __init__(self,name,age):
		self.name=name
		self.__age=age

	def __str__(self):
		'''将对象转化成一个字符串'''
		return  "名字是:{0},年龄是{1}".format(self.name,self.__age)
p=A('lily',18)
print(p)
# 输出:
# 名字是:lily,年龄是18

@property

@property作用:python的一种装饰器,用来修饰方法的。

  • 修饰方法,会将方法转换为相同名称的只读属性。
class A():
	@property
	def funcA_with_property(self):
		return 14
	def funcA_without_property(self):
		return 13
a=A()
a.funcA_with_property # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
# 输出:
# 14
a.funcA_without_property()   #没有加@property , 必须使用正常的调用方法的形式,即在后面加()
# 输出:
# 13

注意: 使用@property进行修饰后,又在调用的时候,方法后面添加了(),那么就会显示错误的信息:TypeError: ‘int’ object is not callable,原因是使用@property后,方法变成了一个属性,如果后面加入(),就是当作函数来调用,而它不是callable(可调用)的。

class A():
	@property
	def funcA_with_property(self):
		return 14
		
a=A()
a.funcA_with_property() 

在这里插入图片描述

  • 与所定义的属性配合使用,可以防止属性被修改。
class A():
	def __init__(self):
		self.name1='lily'
		self.name2='Jack'
		
	@property
	def print_name1(self):
		return self.name1

	@property
	def print_name2(self):
		return self.name2
		
a=A()
a.print_name1
# 输出:
# 'lily'
a.print_name2
# 输出:
# 'Jack'

下面的方法可以参考的使用场景:在A类中调用B类,但是与B类中需要输出的属性配合使用,直接输出某些属性值,如下例,直接输出属性var1,var2。

class A():
    def func_A(self,name1='lily',name2='Jack'):
        names = B(name1,name2)
        return names
        
class B():
    def __init__(self,para1,para2):
        self.var1 = para1
        self.var2 = para2

    @property
    def func_B(self):
        return self.var1
      
    @property
    def func_C(self):
        return self.var2
        
a=A()
result=a.func_A() #result其实是属于B类,打印result出来可以看到"<__main__.B at 0x2b2f3c49910>"
result.func_B
# 输出:
# 'lily'  一直没理解这种方法为什么可以调用出
result.func_C
# 输出:
# 'Jack'

示例:

【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第6张图片
【python基础】类与类的实例化对象、类方法与类的属性、类实例化的方法与属性、初始化函数、类的继承与重写、@property、私有属性与方法_第7张图片
在这里插入图片描述

参考文章:
https://zhuanlan.zhihu.com/p/64487092
上面的例子参考《四、实际应用-实例二-收取邮件的代码封装》


私有属性、私有方法

私有属性与私有方法:通常约定两个下划线开头的属性(方法)是私有的,其他为公共的。

  • 类内部可以访问,类外部不可以访问。
  • 类外部可以通过“_类名__私有属性(方法)名”访问私有属性(方法)。
class A():
	def __init__(self,name,age):
		self.name=name #实例属性
		self.__age=age #私有实例属性
	
	def funcA(self):
		print("实例属性:",self.name)
		print("私有实例属性:",self.__age)
	
	def __funB(self):
		print("私有方法")
p1=A("lily","18")
print(p1.name) 
p1.funcA()
# 输出:
# lily
# 实例属性: lily
# 私有实例属性: 18


print(p1.__age) #直接访问私有属性,报错
p1.__funB() #直接访问私有方法,报错
print(dir(p1)) # ['_A__age', '_A__funB', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'funcA', 'name']

从上面内建函数dir()可以看到其中一些原由,“__age”属性在运行时,属性名被改为了“_A__age”,所以通过“_类名__私有属性(方法)名”访问私有属性,如下面:

print(p1._A__age) #通过这种方式可以直接访问到私有属性。通过dir 可以查到属性:_A__age

另一个通过“_类名__私有属性(方法)名”访问私有属性示例:

class A(object):
    def __init__(self):
        self.__private()
        self.public()
    
    def __private(self):
        print('A.__private()')
    
    def public(self):
        print('A.public()')

class B(A):
    def __private(self):
        print('B.__private()')
    
    def public(self):
        print('B.public()')
    
b = B()
# 输出:
# A.__private()
# B.public()
dir(A)
# 输出:
# _A__private
# __init__
# public

我们可以看到A类中的__private消失了,变成_A__private,因此实际A类变成如下:

class A(object):
    def __init__(self):
        self.__private() # 变成 self._A__private
        self.public()
    
    def __private(self): # 变成 _A__private
        print('A.__private()')
    
    def public(self):
        print('A.public()')


class B(A):
	```
	#继承A类中初始化函数,因此实际继承的如下,所以,输出A.__private()
    #def __init__(self):
    #    self._A__private
    #    self.public()
	```
    def __private(self):
        print('B.__private()')
    
    def public(self):
        print('B.public()')

参考文章:
https://blog.csdn.net/u013250861/article/details/109230731
https://www.cnblogs.com/fengff/p/9290910.html

你可能感兴趣的:(python基础,python,开发语言)