@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)
输出: