property 和 魔法方法
property和魔法方法
三、__doc__, __dict__,__call__,__item__,__len__,__str_
一、property
1.普通的get和set方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang ''' 设计一个银行账户类 包含两个属性: 开户人姓名, 余额 # 注意: # 一个类中全部属性都是私有的话, 那么这个类是无意义的 ''' class Account(object): def __init__(self, name, balance): self.__name = name self.__balance = balance # 实现两个属性的存取器方法 def get_name(self): return self.__name # set def set_balance(self, money): if isinstance(money, int): self.__balance = money else: print("输入类型有误") # get def get_balanc(self): return self.__balance # 存取器方法 # 设置数据 set # 获取数据 get # 命名规则 以set/get _ 属性名 # 使用存取器的好处 # 1. 安全, # 2. 提供了精确的访问控制权限 # 3. 可以对数据进行有效的控制 # 测试 jack = Account('杨', 999999) jack.set_balance(8888) print(jack._Account__name) print(jack.get_name()) print(jack.get_balanc())
2.使用property定义类属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang class Account(object): def __init__(self, name, balance): self.__name = name self.__balance = balance self.__house = '北京' # 实现两个属性的存取器方法 def get_name(self): return self.__name # set def set_balance(self, money): if isinstance(money, int): self.__balance = money else: print("输入类型有误") # get def get_balance(self): return self.__balance # set def set_address(self, new_add): self.__house = new_add # get def get_address(self): return self.__house # del def del_address(self): del self.__house # 使用property 实现一个类属性 name = property(get_name) balance = property(get_balance, set_balance) address = property(get_address, set_balance, del_address, "这个是个地址") jack = Account('杨', 999999) jack.balance = 'aa' print(jack.name) print(jack.balance) print(jack.address) print(Account.address.__doc__) del jack.address print(jack.address)
3.使用property装饰器定义属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang class Account(object): def __init__(self, name, balance): self.__username = name self.__balance = balance self.__house = '北京' # 使用property 装饰器时, 不需要以set/get开头 # @property 只能放在get方法 @property def name(self): return self.__username @property def balance(self): return self.__balance # 当使用 set 方法, 使用的装饰器是 @ 被property装饰的get的方法名, setter # 必须先去装饰 get 方法, 然后才能装饰set方法 @balance.setter def balance(self, money): if isinstance(money, int): self.__balance = money else: print("输入类型有误") @property def address(self): return self.__house @address.setter def address(self, new_add): self.__house = new_add @address.deleter def address(self): del self.__house jack = Account('杨', 999999) print(jack.name) print(jack.balance) jack.balance = '8888' print(jack.address) del jack.address print(jack.address)
二、model,class,bases,mro
__module__ : 这个属性用来获取成员的所属模块
__class__ : 这个属性可以用来一个对象的所属类
__bases__ : 这个属性用来获取当前类的直接父类
__mro__ :这个属性用来获取当前类的 方法解析顺序,在继承时,初始化,查找方法,都是基于这个顺序实现的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang # 动物类 class Animal(object): pass # 人类继承动物类 class Person(Animal): pass # 鸟类继承动物类 class Bird(Animal): pass # 鸟人类继承人类和鸟类,即是多继承,也是多重继承 class BirdMan(Person, Bird): pass # __module__ 这个属性用来获取成员的所属模块 print(BirdMan.__module__) # __class__ 这个属性可以用来一个对象的所属类 bm = BirdMan() print(bm.__class__) # __bases__ 这个属性用来获取当前类的直接父类 print(BirdMan.__bases__) # __mro__ 这个属性用来获取当前类的 方法解析顺序 print(BirdMan.__mro__) # 在继承时,初始化,查找方法,都是基于这个顺序实现的 """ __main__ <class '__main__.BirdMan'> (<class '__main__.Person'>, <class '__main__.Bird'>) (<class '__main__.BirdMan'>, <class '__main__.Person'>, <class '__main__.Bird'>, <class '__main__.Animal'>, <class 'object'>) """
三、__doc__, __dict__,__call__,__item__,__len__,__str__
__doc__ :DocString 可以使用 xxx.__doc__(注意前后都是双_)属性,将 DocString 特性 print 打印出来。
__dict__ :类中的 __dict__ 属性保存了类的所属模块,类中全局变量,方法,DocString 等内容 , 对象中的 __dict__ 属性 用来保存对象的属性
__call__ :使自定义类的实例对象成为可调用对象。
__item__ :使类中的字典或者列表,在实例化的对象上也可以进行正常操作
__len__ :返回字符的长度
__str__ :返回用户的想要返回的值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang """ 测试python当中的文档字符串, DocString 这句就是当前模块的DocString """ class Test(): """ 这个是一个模块中的测试类, 是来测试DocString """ # 方法 def show(self): """ 这个是一个类方法中的DocString """ pass def display(): """ 这个是一个模块内普通函数的DocString """ pass # 实例一个对象 t = Test() print(t.__doc__) print(Test.__doc__) print(t.show.__doc__) print(display.__doc__) print(__doc__) print(print.__doc__)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang class Person(object): ''' __dict__ test''' m = 1 def __init__(self): self.__name = 'tom' self.age = 1 def function(self): print('Function') def __private_function(self): print('Private Function') @staticmethod def static_function(): print('Static Function') @classmethod def class_function(cls): print('Class Function') tom = Person() print(Person.__dict__) print(tom.__dict__) """ {'__module__': '__main__', '__doc__': ' __dict__ test', 'm': 1, '__init__': <function Person.__init__ at 0x000002180502BA60>, 'function': <function Person.function at 0x000002180502BAE8>, '_Person__private_function': <function Person.__private_function at 0x000002180502BB70>, 'static_function': <staticmethod object at 0x000002180502E358>, 'class_function': <classmethod object at 0x000002180502E748>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>} {'_Person__name': 'tom', 'age': 1} """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang """ python 中, 对象可以分为 可变对象 不可变对象 从调用角度 : 可调用对象 和 不可调用对象 callalbe """ # callable 查看对象是否可以调用 # print(callable(1)) # print(callable('a')) # print(callable('')) # print(callable([])) # print(callable({})) def show(): print("show...") show() # print(callable(show())) # 测的是函数的返回值 NONE # print(callable(show)) class Test(object): # 默认情况下, 一个自定义的实例对象是不可调用对象 # 如果想让这个自定义对象变成可调用对象 # 需要实现__call__ def __call__(self, *args, **kwargs): print('call...') # 如果自定义类实现了__call__方法, 那么对象在调用时, 会自动调用__call__方法 # 这种对象叫做仿函数 t = Test() t() print(callable(t))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang class StudentManager(object): '''学生信息管理''' def __init__(self): # 使用字典来保存所有的学生信息 self.__students = {} # 添加学生 def __setitem__(self, key, value): self.__students[key] = value # 获取学生 def __getitem__(self, item): if item not in self.__students: return None return self.__students[item] # 删除学生 def __delitem__(self, key): if key in self.__students: del self.__students[key] # 获取学生人数 def __len__(self): return len(self.__students) # 创建学生管理对象 sm = StudentManager() # 添加两个学生 sm[1] = 'tom' sm[2] = 'jack' # 查看学生个数 print(len(sm)) # 显示添加的学生 print(sm[1]) print(sm[2]) # 删除2号学生 del sm[2] # 查看学生个数 print(len(sm)) # 查看是否删除 print(sm[1]) print(sm[2])
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:Mr.yang my_list = [1,2,3,4,5] # print(len(my_list)) # 5 class Test(object): def __init__(self): self.__list = ['1','2','3','4','5'] # 实现 __str__ , 自定义显示形式 def __str__(self): # return str(self.__list) string = '-'.join(self.__list) return string # 实现 __len__() def __len__(self): return len(self.__list) t = Test() print(t) # len函数会隐式调用对象中的__len__方法 print(len(t))