如何装饰一个类?
为一个类通过装饰,增加一些类属性。
之所以能够装饰,本质上是为类对象动态的添加了一个属性,而这个标识符My指向这个类对象。
def sethu(name): def wrapper(self): self.NAMES=name #print(self) return self #print(wrapper) return wrapper @sethu('xiao hua') class My: pass print(My.__dict__)
普通方法本身都是类的属性,第一个参数必须是self,而self必须指向一个对象,也就是类必须实例化之后,由实例来调用这个方法。
类方法@classmethod 方法上面加装饰器
class Xi: aha="类属性" def foo(self): print("foo") def bar(): print("bar") @classmethod def xy(cls):#类方法 print(cls.aha) @staticmethod def jing():#静态方法 print("jing") a=Xi() print(a.foo()) Xi.bar() #a.bar()#报错TypeError: bar() takes 0 positional arguments but 1 was given print(Xi.__dict__) Xi.xy() a.xy()#a.__class__.xy() Xi.jing() a.jing()
访问控制
私有(Private)属性
使用双下划线开头的属性名,就是私有属性;
私有变量的本质:类定义的时候,如果声明一个实例变量的时候,使用双下划线,Python解释器会将其改名,转换名称为_类名__变量名的名称,所以用原来的名字访问不到了。
知道了私有变量的新名称,就可以直接从外部访问并修改。
class Person: def __init__(self,name,age=18): self.name=name self.__age=age def growup(self,up=1): if 0<up<150: self.__age+=up def getage(self): return self.__age a=Person("xixi") a.growup() #print(a.__age) #或a.age,报错 print(a.getage()) print(Person.__dict__) print(a.__dict__) print(a._Person__age) a._Person__age=500 print(a.getage())
class Person: def __init__(self,name,age=18): self.name=name self.__age=age def growup(self,up=1): if 0<up<150: self.__age+=up def getage(self): return self.__age a=Person("xixi") a.growup() a.age=1000#赋值即定义,增加一个属性 print(a.getage()) print(a.age) print(a.__dict__)
保护变量
在变量名前使用一个下划线,称为保护变量。
可以看出,_name属性根本就没有改变名称,和普通的属性一样,解释器不做任何特殊处理。
这知识开发者共同的约定,看见这种变量,就如同私有变量,不要直接使用。
class Person: def __init__(self,name,age=18): self._name=name self.__age=age a=Person("xixi") a._name="huala" print(a._name) print(a.__dict__)
私有方法
class Person: def __init__(self,name,age=18): self._name=name self.__age=age def __getage(self):#私有方法 return self.__age a=Person("xixi") print(Person.__dict__) print(a.__dict__) #print(a.__getage())#AttributeError: 'Person' object has no attribute '__getage' print(a._Person__getage())