# 对象的基本理论 # 什么事对象? # 万物皆对象 # 对象是具体物体 # 拥有属性 # 拥有行为 # 把很多零散的东西,封装成为一个整体 # 举例:王二小 # 属性 # 姓名 # 年龄 # 身高 # 体重 # 行为 # 走路 # 吃饭 # 放羊 # Python中的体现 # 是一门特别彻底的面向对象编程(OOP)的语言 # 其他语言:基本数据类型,对象类型 # python全部类型都是对象类型 # 面向对象是面向过程的封装 # 对象和类的关系:对象 可以抽象为类 类可以实例化为对象 class Money: pass print(Money) #<class ‘__main__.Money‘> one = Money() print(one, type(one)) #<__main__.Money object at 0x030CFBB0> <class ‘__main__.Money‘> class Person: pass # 对象的操作:增 p = Person() # 查看对象的所有属性 print(p.__dict__) #{} p.age = 18 p.height = 180 print(p.__dict__) #{‘age‘: 18, ‘height‘: 180} # 对象的操作:删 del p.age # 对象的操作:改 p.height = 185 # 对象里面如果有这个属性,就是修改,否则就是增加这个属性 # 类里面的 __dict__ 不可以修改,只读的 # 对象里的 __dict__ 可以修改 class Test: age = 18 #Test.__dict__["age"] = 20 #TypeError: ‘mappingproxy‘ object does not support item assignment one = Test() one.__dict__ = {"name":"abc", "height":180} #就是说__dict__字典里面生存储属性的变量 print(one.__dict__) #{‘name‘: ‘abc‘, ‘height‘: 180} # 理解下面的内容 class Person: age = 10 p = Person() print(Person.age) # 10 print(p.age) # 10 p.age += 5 # p.age = p.age + 5 # 要理解这个在对象和类的操作方法:首先是计算右边的值,p.age 在对象p中没有,所以他要到类中去取age = 10 # 然后变成10+5 = 15, 然后在p对象中新增加个age属性(以前说过,对象没有就是新增,有的话就是修改) print(Person.age) # 10 print(p.age) # 15 # __slot__ class Person: __slots__ = {"age"} #只可以加入age的属性 p1 = Person() p1.age = 18 print(p1.age) # 方法:实例方法,类方法,静态方法 class Person: def eat(self): print("这是个实例方法", self) @classmethod def eat2(cls): print("这是个类方法", cls) @staticmethod def eat3(): print("这是个静态方法") p = Person() print(p) p.eat() p.eat2() p.eat3() # <__main__.Person object at 0x032F54F0> # 这是个实例方法 <__main__.Person object at 0x032F54F0> # 这是个类方法 <class ‘__main__.Person‘> # 这是个静态方法 print("-" * 30) #另外的调用方式: Person.eat("123") #这里必须要有个参数,才能调用成功 Person.eat2() Person.eat3() print("-" * 30) # 实例方法,类方法,静态方法的访问权限问题(包括类属性,实例属性) class Person: age = 10 # 实例方法 def shilie(self): print(self) print(self.age) print(self.num) # 类方法 @classmethod def leifangfa(cls): print(cls) print(cls.age) print(cls.num) # 不可以使用实例属性 # 静态方法 @staticmethod def jingtai(): print(Person.age) # 能使用类里面的属性,但很少这样去调用的 p = Person() p.num = 11 p.shilie() # 实例方法:可以调用实例属性和类属性 #p.leifangfa() # 类方法:不可以使用实例属性 p.jingtai() # 静态方法:可以使用类属性,不可以使用实例属性 # 元类 num = 123 str = "abc" print(num.__class__.__class__) # <class ‘type‘> print(str.__class__.__class__) # <class ‘type‘> print(Person.__class__) # <class ‘type‘> print(Person.__class__.__class__)# <class ‘type‘> print(p.__class__.__class__) # <class ‘type‘> # ----------------------------另外一种创建类的方式------------------------- def run(self): print(self) dog = type("Dog",(),{"name":"abc","run":run}) #字典里面可以是类属性,或者类方法 print(dog.name) #abc print(dog.run) #<function run at 0x02B56C90> # ---------------------------类的创建流程---------------------------------- class Animal: # __metaclass__ = xxx pass class Person(Animal): # __metaclass__ = xxx pass # -------------------------类的描述, pydoc 模块--------------------------------------- class Person: """ 关于类的描述,类的左右,类的构造函数 Attribute: 属性的描述 """ def run(self, distence, step): """ 函数的作用 :param distence:参数含义,数据类型,默认值 :param step: :return: 返回值类型 """ return distence / step # help(Person) # 可以这样看帮助文档 # ------------------------ 私有化属性(类的内部,子类内部,模块内部,模块外部)4大块 ------- class Animal: x = 10 _y = 20 __z = 30 def test(self): print(Animal.x) print(self.x) print(Animal._y) print(self._y) print(Animal.__z) print(self.__z) print("-" * 30) class Dog(Animal): def test2(self): print(Dog.x) print(self.x) print(Dog._y) print(self._y) # print(Dog.__z) # 错误 # print(self.__z) # 错误 print("-" * 30) # 类的内部访问 a = Animal() a.test() # 成功打印x # 子类的内部访问 d = Dog() d.test2() # 成功打印x # 模块内部访问 # print(Animal.x) # 成功打印x # print(Dog.x) # 成功打印x # print(a.x) # 成功打印x # print(d.x) # 成功打印x # print(a.__z) # 有错误 # # print(Animal._y) # 成功打印_y,但有警告 # print(Dog._y) # 成功打印_y,但有警告 # print(a._y) # 成功打印_y,但有警告 # print(d._y) # 成功打印_y,但有警告 # print(a.__z) # 有错误 # print(d.__z) # 有错误 print(Animal.__dict__) print(Animal._Animal__z) # 伪私有 30 # 模块外的访问 import public print(public.num) # 成功打印num print(public._num2) # 另外一种模块导入方法 from public import * # 直接写public 模块中的变量 print(num) # 成功打印num # print(_num2) # 有错误