21 @property、静态方法和类方法(反射)

本文深入探讨Python中的装饰器,包括@property、@classmethod和@staticmethod的使用场景及区别,并详细解析反射机制(hasattr、getattr、setattr、delattr)及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@property

内置装饰器函数,只在面向对象中使用。

from math import pi
class Circle:
	def __init__(self,r):
		self.r = r
	@property
	def perimeter(self):
		return 2 * pi * self.r
	@property
	def area(self):
		return self.r ** 2 * pi
c1 = Circle(5)
print(c1.area)

@property的作用就是将一个方法,变成一个属性,注意,这个方法在定义的时候,不能传递参数。

classmethod 类方法

当一个方法的操作只涉及静态属性的时候,应该使用@classmethod来装饰这个方法。

class Goods:
    __discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price * Goods.__discount
    @classmethod   # 把一个方法 变成一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象
    def change_discount(cls,new_discount):  # cls是必须写的,类似于self  修改折扣   
        cls.__discount = new_discount
apple = Goods('苹果',5)
print(apple.price)
Goods.change_discount(0.5)   # Goods.change_discount(Goods)
print(apple.price)

staticmethod 静态方法

在完全面向对象的程序中,如果一个函数既和对象没有关系,也和类没有关系 那么就用@staticmethod将这个函数变成一个静态方法。

class Login:
    def __init__(self,name,password):
        self.name = name
        self.pwd = password
    def login(self):pass

    @staticmethod
    def get_usr_pwd():   # 静态方法
        usr = input('用户名 :')
        pwd = input('密码 :')
        Login(usr,pwd)

Login.get_usr_pwd()

类方法和静态方法都是类调用的。
对象可以调用类方法和静态方法么?答案是可以的,一般情况下推荐用类名调用。类方法有一个默认参数cls代表这个类。静态方法没有默认的参数,就象函数一样。

穿插两个内置判断方法

isinstance(obj,a)	#判断obj是否是a类型的对象。返回True或者False

issubclass(sub,super)	#检查sub类是否是super类的派生类。

反射(hasattr、getattr、setattr、delattr)

用字符串类型的名字,去操作变量。非常重要!!!!!(五颗星*****)

getattr

通过变量名的字符串形式取到值

class Teacher:
    dic = {'查看学生信息':'show_student','查看讲师信息':'show_teacher'}
    def show_student(self):
        print('show_student')

    def show_teacher(self):
        print('show_teacher')

    @classmethod
    def func(cls):
        print('hahaha')

ret = getattr(Teacher,'dic')	#相当于调用Teacher.dic,且是通过变量名的字符串取到的值
ret2 = getattr(Teacher,'func')	#反射对象中的方法,方法名通过字符串表示。得到的是一个内存地址。
print(ret2())
print(ret)

输出:
输出结果

hasattr

hasattr与getattr经常一起使用,hasattr当作一个判断语句使用。

class Teacher:
    dic = {'查看学生信息':'show_student','查看讲师信息':'show_teacher'}
    def show_student(self):
        print('show_student')

    def show_teacher(self):
        print('show_teacher')

    @classmethod
    def func(cls):
        print('hahaha')

# for k in Teacher.dic:
#     print(k)
zhangsan = Teacher()
key = input('输入需求:')
# print(Teacher.dic[key])
if hasattr(zhangsan,Teacher.dic[key]):
    func = getattr(zhangsan,Teacher.dic[key])
    func()

输出:
输出结果

反射类方法和反射对象的方法是一样的,反射同样可以作用在模块上 。

那怎么在本py文件中使用反射呢:

def func():
	print('hahahaah')
name = '反射'
import sys
# print(sys.modules)       #可以打印当前导入的模块
# print(sys.modules['__main__']) #打印当前文件模块的内存地址
#__name__是等于'__main__'的
print(getattr(sys.modules[__name__],'func'))	#反射自己模块中的方法
print(getattr(sys.modules[__name__],'name'))	#反射自己模块中的变量。

输出:
在这里插入图片描述

setattr 设置修改变量名
class A:
	pass
a = A()
setattr(A,'name','zhangsan')
setattr(a,'name','lisi')
print(A.name)	#存在类的内存空间
print(a.name)	#存在对象内存空间

输出:
在这里插入图片描述

delarrt 删除一个变量
class A:
	pass
a = A()
setattr(A,'name','zhangsan')
setattr(a,'name','lisi')
delattr(a,'name') #首先把对象a中的name属性删除了,a中没有了name属性,就会在A中找
print(a.name)

输出:
在这里插入图片描述

class A:
	pass
a = A()
setattr(A,'name','zhangsan')
setattr(a,'name','lisi')
delattr(a,'name') #首先把对象a中的name属性删除了,a中没有了name属性,就会在A中找
print(a.name)
delattr(A,'name')   #A中的name属性的值也没有了,会报错
print(a.name)

输出:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值