面向对象:
静态字段:
class province:#静态字段 country = "china" #静态字段存在的意义就是对每个对象中重复的东西在类里边保存一份,此处hebei,henan就是两个对象,都可以访问到 #上述静态字段,所以它是重复的 def __init__(self,name): self.name = name def show(self): print(province.country,self.name) hebei = province("河北") hebei.show() henan = province("河南") henan.show()
静态方法:
class Foo():@staticmethod def static(): print("stattic") #静态方法括号内没有self,但可以加上其它参数,且方法前要加上@staticmethod #静态方法使用 类名+方法名 即可执行 Foo.static() #静态方法也可以通过对象去调用 obj = Foo() obj.static()
类方法:
#类方法就是将类本身作为对象进行操作的方法 class Foo:name = "aaa" # 创建类方法的时候需要在方法前面加上@classmethod,其第一个参数是类,约定写cls @classmethod def ClassMethod(cls): #类方法的参数是当前类的类名 cls = Foo,类对象和实例都可以调用类方法 print(cls.name) # 调用类方法 类对象 = Foo 类实例 = obj Foo.ClassMethod()
面向对象成员修饰符:
成员修饰符就是设置类的成员有些是公开的有些是私有的,公开的是在外部通过对象或者类可以调用,但是私有的只能通过类的内部才可以调用。
静态字段和私有静态字段:
class Foo:# 公有的静态字段 ClassMembers = "公开的" # 私有的静态字段 __ClassMembers = "私有的" # 执行公有的静态字段 print(Foo.ClassMembers) # 执行私有的静态字段,会报错,因为私有的“只能”通过类的内部才可以调用,后边其实还有别的办法可以实现调用 print(Foo.__ClassMembers)
#注意:此处应明确类对象Foo可以访问静态字段,但是不能直接访问类中的方法,需要实例进行访问,即obj,可与下一张图作对比
做如下修改,在类中调用私有字段
class Foo:# 私有的静态字段 __ClassMembers = "私有的" # 通过类中的方法调用私有的静态字段进行输出 def Members(self): print(Foo.__ClassMembers) # 创建一个对象 obj = Foo() # 执行类中的Members方法 obj.Members()
普通字段和私有普通字段:
class Foo:# 类的构造方法 def __init__(self, url): # 普通字段 self.url = url # 私有普通字段,明确普通字段和静态字段的差别. self.__Blog = url # 创建一个对象,传入一个值 obj = Foo("http://ansheng.me") # 普通字段 print(obj.url) # 私有的普通字段 print(obj.__Blog)#此句执行不成功 #普通字段定义在方法里,只有当对象创建之后才会有普通字段,而且只能通过对象来调用 #静态字段属于类,解释器在加载代码的时候已经创建,对象和类都可以调用
若要输出私有的普通字段,需要在类中调用私有的普通字段进行输出
class Foo:# 类的构造方法 def __init__(self, url): # 私有普通字段 self.__Blog = url # 在类中调用私有普通字段进行输出 print(self.__Blog) # 创建一个对象,传入一个值 obj = Foo("http://ansheng.me")
总结如下:普通字段,静态字段,普通私有字段,静态私有字段
普通字段在方法中定义(构造方法)
普通字段创建对象后才会建立
普通字段只能通过对象调用
普通私有字段在类中调用输出
可以在创建对象时直接传参数输出
对于私有成员,只能在类中调用,即使是继承也不行
通过特殊方法访问类中的私有成员:
class Foo:def __init__(self): # 私有普通字段 self.__Blog = "http://ansheng.me" # 创建一个对象 obj = Foo() # 通过特殊的方法访问 print(obj._Foo__Blog) # 一个下划线,一个类名,私有的变量名
私有方法:
class Fun:#私有方法,直接访问不到,可以通过公有方法进行访问 def __sha(self): print("我是谁") #公有方法 def foo(self): self.__sha() obj = Fun() obj.foo() obj._Fun__sha()#也可以实现调用,功能同上,但不建议使用
特殊成员:__call__
class SpecialMembers:# 类的构造方法 def __init__(self): print("My Blog is Url: http://ansheng.me") # 对象的构造方法 def __call__(self): print("My Name is: Ansheng") # 创建一个对象,并且执行类的构造方法 obj = SpecialMembers() # 执行对象的构造方法 obj() # 先执行类的构造方法,然后在执行对象的构造方法 SpecialMembers()()
__dict__获取类或对象中的所有成员
class SpecialMembers:def __init__(self): self.Name = "Ansheng" self.Blog = "https://blog.ansheng.me" # 获取类中的成员 print(SpecialMembers.__dict__) obj = SpecialMembers() # 获取对象中的成员 print(obj.__dict__)
__iter__
一个对象如果可以被for循环迭代,说明对象中有__iter__方法,且方法中有yield值。
class SpecialMembers:def __iter__(self): yield 1 yield 2 yield 3 # 创建一个对象 obj = SpecialMembers() # 如果执行for循环对象时,自动会执行对象的__iter__方法,此时的__iter__就是一个生成器 for i in obj:#obj对象被for循环迭代 print(i)
面向对象类成员特性
Property:把类方法当成普通字段去调用,即用对象调用的时候后面不用加括号
class Foo:@property def Characteristic(self): print("类方法的特性") # 创建一个对象 obj = Foo() # 调用类方法的时候方法后面不用加括号 obj.Characteristic
类的继承:
经典类和新式类:
经典类:多重继承情况下,会按照深度优先方式查找
新式类:多重继承情况下,会按照广度优先方式查找
新式类:当前类或者父类继承了object类,那么该类便是新式类
经典类查找:
class D:def bar(self): print('D.bar') class C(D): def bar(self): print('C.bar') class B(D): def bar(self): print( 'B.bar') class A(B, C): def bar(self): print("A.bar") a = A() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> D --> C # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了 a.bar()
新式类多继承
class D(object):def bar(self): print('D.bar') class C(D): def bar(self): print('C.bar') class B(D): def bar(self): print('B.bar') class A(B, C): def bar(self): print( 'A.bar') a = A() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> C --> D # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了 a.bar()