• 面向过程:简单问题 线性思维解决 具体到微观操作
  • 面向对象:复杂问题 宏观把握事物之间的联系 方便分析整个系统

一、object类

所有的类默认继承Objecct类
(1)特殊方法
①dir(对象) :返回该对象具有的所有属性,从Object类中继承
②__str__()方法:用于返回一个对象的描述 常用于print方法,帮助查看对象的信息,可以对__str__()进行重写

class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __str__(self):
        return 'my name is {0} , {1} years old'.format(self.name,self.age)


stu =Student("zhangsan",20)
print(dir(stu))
print(stu) #默认调用__str__方法 可以重写这个方法 返回对对象的描述
print(type(stu))

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
my name is zhangsan , 20 years old #重写前 默认的对象描述为<__main__.Student object at 0x000001B654818400>
<class '__main__.Student'>

③__add__():实现了两个对象的加法运算

class Student:
    def __init__(self,name):
        self.name = name

    def __add__(self, other):
        return self.name+other.name


stu1=Student("zhangsan")
stu2=Student("lisi")
s=stu1+stu2
print(s)  #zhangsanlisi
s=stu1.__add__(stu2)
print(s)  #zhangsanlisi

④__len__():相当于len(),对没有len()的对象重写__len__()

class Student:
    def __init__(self,name):
        self.name = name

    def __len__(self):
        return len(self.name)

stu1=Student("zhangsan")
print(stu1.__len__()) #8

⑤__new__()和__init__()
new在前创建对象,init对对象的属性进行赋值

class Person(object):
    def __new__(cls, *args, **kwargs):
        print("__new__被调用执行了,cls的id值{0}".format(id(cls)))
        obj = super().__new__(cls)
        print("创建的对象的id为:{0}".format(id(obj)))
        return obj

    def __init__(self,name,age):
        print('__init__被调用了,self的id值为:{0}'.format(id(self)))
        self.name = name
        self.age = age


print("object对象的id为:{0}".format(id(object)))
print("Person对象的id为:{0}".format(id(Person)))

p1 = Person("zhangsan",20)
print("p1这个实例对象的id为:{0}".format(id(p1)))

object对象的id为:140734945672016
Person对象的id为:2046457094576
__new__被调用执行了,cls的id值2046457094576
创建的对象的id为:2046488192048
__init__被调用了,self的id值为:2046488192048
p1这个实例对象的id为:2046488192048

python object取值 python object方法_object

(2)特殊属性
①__dict__
实例对象.dict:实例对象的属性字典
类.dict:类的属性和方法字典
②__class__ :输出了对象所属的类
③__bases__:类的父类类型元素
base :基类 类的最前面的父类类型元素
⑤__mro__:类的层次结构
⑥__subclasses()__:类的子类列表

class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name = name
        self.age = age

x=C("zhangsan",20)
print(x.__dict__) #{'name': 'zhangsan', 'age': 20}
print(C.__dict__) #{'__module__': '__main__', '__init__': <function C.__init__ at 0x000002C37F32E280>, '__doc__': None}

print(x.__class__) #<class '__main__.C'>

print(C.__bases__) #(<class '__main__.A'>, <class '__main__.B'>)
print(C.__base__)  #<class '__main__.A'>

print(C.__mro__)   #(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

print(A.__subclasses__()) #[<class '__main__.C'>, <class '__main__.D'>]

二、 类与对象

1.类的组成:

  • 类属性:直接写在类里的变量,类内共享;类和对象均可以直接访问
  • 实例属性:init赋值
def __init__(self,age,name):
	self.age = age
	self.name = name
  • 实例方法:类内函数
def eat(self):
	print("实例方法")
  • 静态方法:@staticmethod修饰 使用类名直接访问的方法
@staticmethod
def method():
	print("静态方法")
  • 类方法:@classmethod修饰 使用类名直接访问的方法
@classmethod
def cm(cls):
	print("类方法")

2.调用

stu1=Student("20","zhangsan")
stu1.eat()
Student.eat(stu1)

3.动态绑定

stu1.gender='女' #为stu1对象单独绑定属性
def drink():
	print("heshui")
stu1.drink=drink  #为stu1对象单独绑定方法

4.面向对象的三大特征

  • 封装:安全性
    python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外被访问,前边使用两个“_”
class Student:
	def __init__(self,name,age):
		self.name = name
		self.__age = age   #age不希望在类的外部被使用
	def show(self):
		print(self.name,self.__age) #age在类的内部可以被访问


stu = Student("zhangsan",20)
stu.show() #zhangsan 20
print(stu.name) #zhangsan 
print(stu.__age) #没有这个属性可访问
print(dir(stu)) #显示stu所有可访问的属性 没有__age 但是有Student__age
print(stu.Student__age) #20 在类的外部可以通过Student__age进行访问
  • 继承:代码复用性
    python支持多继承;
    若一个类没有继承任何类,默认继承Object;
    定义子类时,必须在其构造函数中调用父类的构造函数
    super()调用父类方法
    override方法重写
class Person(object):
	def __init__(self,name,age):
		self.name = name
		self.age = age
	def info(self):
		print(self.name,self.age)

class Student(Person):
	def __init__(self,name,age,stu_no):
		super().__init__(name,age)
		self.stu_no = stu_no
	 #override方法重写
	def info(self):
		super().info() #调用父类的方法
		print(self.stu_no) #加入子类的扩展实现
		

class Teacher(Person):
	def __init__(self,name,age,teachofyear)
		super().__init__(name,age)
		self.teachofyear = teachofyear
	#override方法重写	
	def info(self):
		super().info() #调用父类的方法
		print(self.teachofyear) #加入子类的扩展实现

stu = Student("zhangsan",20,"1001")
teacher = Teacher("lisi",35,10)

stu.info() #重写前zhangsan 20 重写后 zhangsan 20 1001 
teacher.info() #重写前lisi 35 重写后 zhangsan 35 10
#多继承 C同时继承了A和B
class A(object):
	pass
class B(object):
	pass
class C(A,B):
	pass
  • 多态:可扩展性和可维护性
    不知道一个变量引用的对象是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据引用对象的类型,动态决定调用那个对象中的方法
    (1)静态语言(Java)实现多态:必要条件①继承②方法重写③父类引用指向子类对象
    (2)动态语言(Python)实现多态:“鸭子类型”,不关注对象是什么类型,只关心对象的行为
class Animal(object):
    def eat(self):
        print("动物会吃")
          
class Dog(Animal):
    def eat(self):
        print("狗吃骨头...")  
        
class Cat(Animal):
    def eat(self):
        print("猫吃鱼...")
               
class Person:
    def eat(self):
        print("人吃五谷杂粮")
                
def fun(obj):
    obj.eat()


fun(Cat()) #猫吃鱼...
fun(Dog()) #狗吃骨头...
fun(Animal()) #动物会吃
fun(Person()) #人吃五谷杂粮