【三十四】类、对象、变量、方法

类、对象、变量、方法

在实例化时,会先自动调用__new.__(cls)魔术方法,把类对象和其他的实参一起打包,把实例化的类对象作为实参传给cls,__new__会根据该类对象创建出一个实例对象,__new__再调用__init__(self),把该实例对象作为实参传递给self,把刚刚打包的其他实参传给__init__的其他形参,然后通过____init____方法对该实例对象进行属性的初始化操作,最后由__new__把初始化属性之后的实例对象返回出来

实例对象是由__new__会根据该类对象创建出一个实例对象,__new__创建并返回的,____init___只是起到加工的作用,所以__init__不能有返回值(必须返回None)

类变量、实例变量、实例化

# 定义一个类对象,类的名字首字母通常大写
class Student(object): # object 是所有类的基类, 通常省略不写
    
    school = '二中' # 类变量

    def __init__(self, name):
        self.name = name # 实例变量

"""

对__new__(cls)方法介绍:
构造方法。它会将请求实例化所属的类作为实参传给cls(其他实参传给
__init__), 创建并返回这个类的实例对象, 通常不需要显示的声明该方
法, 因为父类的 object 中有定义

对__init__(self)方法介绍:
初始化方法。用来定制实例变量, 返回值只能是None(因为负责返回实例
对象的是构造方法)

"""

"""

实例化时, 会先调用__new__(cls)方法, 在实例对象被创建之后且返回
给调用者之前,
再调用__init__(self)方法, 把实例对象传给self参数, 做进一步的定
制

"""
stu1 = Student('小明') # 实例化, 得到实例对象stu1
stu2 = Student('小红') # 实例化,得到实例对象stu2

""" 实例变量的调用规则 """
print(stu1.name) # 实例对象stu1调用实例变量
print(stu2.name) # 实例对象stu2调用实例变量
# print(Student.name) # 类对象调用不到实例变量

""" 类变量的调用规则 """
print(Student.school) # 类对象可以直接调用类变量(推荐)
print(stu1.school) # 实例对象stu1也可以调用类变量
print(stu2.school) # 实例对象stu2也可以调用类变量

""" 实例变量是每个实例对象所独有的 """
stu1.name = '小强' # 把实例对象stu1的name变量指向新的值
print(stu1.name) # 实例对象stu1再次调用实例变量, 输出新的值

print(stu2.name) # 而实例对象stu2再次调用实例变量, 并不受到
影响
""" 类变量在整个实例对象中是公用的
类对象调用类变量重新赋值, 会影响所有的对象对该类变量的调用 """
Student.school = '一中' # 把Student类的school变量指向新的值
print(Student.school) # 类对象再次调用类变量, 输出新的值
print(stu1.school) # 实例对象stu1再次调用类变量, 也输出新的print(stu2.school) # 实例对象stu2再次调用类变量, 也输出新的""" 实例对象调用类变量重新赋值, 其实是在动态定义变量, 根本与类变
量无关 """
stu1.school = '三中' # 动态定义变量,定义了stu1对象的一个实例
变量
print(stu1.school) # 实例对象stu1调用上一步定义的实例变量
print(Student.school) # 而类变量还是那个类变量
print(stu2.school) # 而类变量还是那个类变量

类方法、对象方法、静态方法

  • 在 Python 中,一般把定义在类中的函数叫方法(method),不在类中的叫函数(function)
  • 方法通常有参数,比如对象方法隐式的接收了 self 参数,类方法隐式 的接收了 cls 参数
  • 函数可以没有参数
class Student:
    
	@staticmethod # 静态方法 装饰器
	def eat():
		print('我要开动了~')
        
	@classmethod # 类方法 装饰器
    def sleep(cls): # cls表示当前调用的类对象
  	    print('我要就寝了~')
        
    def init(self, age): # self表示当前调用的实例对象
   	    self.age = age
		print(f'我{self.age}岁开始学习')
        
        
# self, cls不是关键字,可以换成自己写的其他任意名字代替,调用的
时候统一就可以了
# 静态方法:类可以直接调用,实例对象也可以调用,推荐类调用
# 类方法:类可以直接调用,实例对象也可以调用,推荐类调用
# 对象方法:实例对象调用,类不可调用

stu = Student()
Student.eat()
Student.sleep()
stu.eat()
stu.sleep()

# print(stu.age) # 报错(stu没有age变量)
stu.init(7) # 可能会碰到另外一种写法:Student.init(stu, 7)
print(stu.age) # 不报错(上一步调用方法之后, 创建了self.age变量)

思考:静态方法、类方法有什么区别?

class A:
    
	var1 = 123
    
	@classmethod
	def func1(cls):
		print(cls.var1)
        
	@staticmethod
	def func2():
		print(A.var1)
        
class B(A):
    
	var1 = 321
    
    
A.func1()
A.func2()
B.func1()
B.func2()

动态定义变量

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
        
    def show_info(self):
    	print(f'名字:{self.name}, 年龄:{self.age}, 地址:{self.address}')
        
        
    def study1(self):
        self.course = "语文"
		print(f'今天学习的科目是:{self.course}')
        
	def study2(self):
		print(f'今天学习的科目是:{self.course}')
        
        
stu1 = Student('张三', 18) # 实例化
stu2 = Student('小明', 28) # 实例化

# stu1.show_info() # 报错(因为stu1没有address变量)

stu1.address = '黄土高坡' # stu1动态定义实例变量
print(stu1.address) # 输出: 黄土高坡
# print(stu2.address) # 报错(因为实例变量是每个实例对象所独有的)

stu1.show_info() # 不报错(因为stu1动态定义了address变量)

# stu2.study2() # 报错(因为stu2没有course变量)
stu2.study1() # 不报错(因为study1方法中定义了course变量)
stu2.study2() # 不报错(因为study1方法执行之后, course变量已经被定义了)

stu2.course = '数学' # 动态定义实例变量
stu2.study1() # study1方法中会把self.course重写赋值

class Worker:
	def __init__(self, name):
		self.name = name
        
        
wk = Worker('李四')
Worker.factory = "江南皮革厂" # 动态定义类变量
print(Worker.factory) # 类对象调用类变量(推荐)
print(wk.factory) # 实例对象也可以调用类变量

# print(Worker.name) # 报错(类对象调用不到实例变量)
Worker.name = '王五' # 动态定义类变量
print(Worker.name) # 类对象调用类变量
print(wk.name) # 实例对象优先调用实例变量name, 而不调用类变量name
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值