什么是对象
万物皆对象
对象是具体的物体:有属性、行为,将很多零散的东西,封装为一个整体。
python是一门特别彻底的面向对象编程(OOP)的语言。所有都属于对象。
面向过程/面向对象
面向过程:在解决问题的时候,关注的是解决问题的每一个过程(步骤。
面向对象:在解决问题的时候,关注的是解决问题所需要的对象。
面向对象本身是对面向过程的封装
面向过程:重要的是按照步骤划分任务。
面向对象:按照步骤抽象成对象,确定属性和行为
类
某一个具体对象特征的抽象
作用:根据抽象的类,生成具体的对象
组成
名称、属性(静态的特征值)、方法(动态的操作):均是抽象的概念,在生产对象之后,才拥有具体的内容
![]()
定义类
大驼峰:英文首字母需要大写
class yawen:
pass
ya = yawen()
print(type(ya))
实例化对象
Money也是变量名称
class Money:
pass
one = Money()
print(one) #<__main__.Money object at 0x000001EEC60F2A90>
print(type(one)) #<class '__main__.Money'>
print(one.__class__) #<class '__main__.Money'>
属性
对象属性
增加:对象.属性
class Person:
pass
p = Person()
p.age = 18
print(p.age) #18
#查看所有属性
print(p.__dict__) # {'age': 18}
查:访问对象没有的属性会报错
AttributeError: 'Person' object has no attribute 'sex'
修改:对象.属性 = 新的值
p.age = 20
print(p.age) #20
p.age = 20
print(p.age) #20
p.pets = ["小猫", "小狗", "小黑"]
print(p.pets, id(p.pets)) #['小猫', '小狗', '小黑'] 2368269277632
p.pets.append("小蔡")
print(p.pets, id(p.pets)) #['小猫', '小狗', '小黑', '小蔡'] 2368269217408
p.pets = [1]
print(p.pets, id(p.pets)) #[1] 2368269429120
删除:del p.属性
del p.age
print(p.age) #AttributeError: 'Person' object has no attribute 'age'
不同的对象之间不能互相访问属性。
类属性
类 其实也是一个对象,不过类是对象的模板。
增加
class Money:
pass
Money.age = 18
print(Money, Money.age)#<class '__main__.Money'> 18
print(Money.__dict__)#{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Money' objects>, '__weakref__': <attribute '__weakref__' of 'Money' objects>, '__doc__': None, 'age': 18}
class Money:
pass
Money.age = 18
print(Money, Money.age)#<class '__main__.Money'> 18
print(Money.__dict__)#{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Money' objects>, '__weakref__': <attribute '__weakref__' of 'Money' objects>, '__doc__': None, 'age': 18}
查询属性
class Money:
age = 19
count = 1
one = Money()
print(one.__class__)#<class '__main__.Money'>
修改属性
class Money:
age = 19
count = 1
Money.age = 22
print(Money.age)#22
删除属性
del 类名.属性
del语句只删除直系属性
class Money:
age = 19
count = 1
one = Money()
del Money.age
#Money是type类型的对象
print(Money.age)#type object 'Money' has no attribute 'age'
print(one.age)#AttributeError: 'Money' object has no attribute 'age'
class Money:
pass
one = Money()
one.__dict__ = {"name" : "niko", "age" : 18}
print(one.name)#niko
一般情况下,属性存储在__dict__的字典中,有些内置的对象没有__dict__这个属性
一般对象可以直接修改__dict__属性
但类的dict属性是只读,是不能写的。只可以通过setattr方式修改
类的属性由对象共享,如果类的属性修改,则对象属性应该做对应的修改。
class Money:
age = 18
one = Money()
two = Money()
print(one.age, two.age)
Money.age = 20
print(one.age, two.age)
限制类可以添加的属性
__slots__ = [list]
class Person:
__slots__ = ["age"]
p1 = Person()
p1.age = 9
p1.num = 10 #AttributeError: 'Person' object has no attribute 'num'
私有化属性
python没有私有化支持,但是可以用下划线完成伪私有的效果
类属性和实例属性遵从同样的规则
y:公有属性
_y:受保护的属性
__y:私有属性
#公有属性
#类内部访问 子类内部访问 模块内其他位置访问 跨模块访问(import 导入 from import 导入)
class Animal:
x = 10
def test(self):
print(Animal.x)
pass
class Dog(Animal):
def test(self):
print(Dog.x)
pass
a = Animal()
a.test()#10 类的内部可以访问到x
dog = Dog()
dog.test()
print(Animal.x)#10
print(Dog.x)#10
#受保护的属性
#类内部访问 子类内部访问 模块内其他位置访问(会有警告 可以强行访问)
#跨模块访问(import 导入也可以强行访问 from import 导入不能访问)
#可以在源文件加入__all__=[list],然后就可以使用from import *访问
class Animal:
_x = 10
def test(self):
print(Animal._x)
pass
class Dog(Animal):
def test(self):
print(Dog._x)
pass
a = Animal()
a.test()#10 类的内部可以访问到x
dog = Dog()
dog.test()
print(Animal._x)#10
print(Dog._x)#10
#私有属性
#类内部访问
#不可子类内部访问
#不可模块内其他位置访问
#跨模块访问(import 导入可以访问 from import 导入不能访问,__all__的技巧也可用)
class Animal:
__x = 10
def test(self):
print(Animal.__x)
pass
class Dog(Animal):
def test(self):
print(Dog.__x)
pass
a = Animal()
a.test()#10 类的内部可以访问到x
dog = Dog()
dog.test()#type object 'Animal' has no attribute '__x'
print(Animal.__x)#type object 'Animal' has no attribute '__x'
print(Dog.__x)#type object 'Animal' has no attribute '__x'
私有属性的实现机制:名字重整:重改__x为另外一个名称,如_类名__x
目的:
1、防止外界直接访问
2、防止被子类同名称属性覆盖
#私有属性
#类内部访问
#不可子类内部访问
#不可模块内其他位置访问
#跨模块访问(import 导入可以访问 from import 导入不能访问,__all__的技巧也可用)
class Animal:
__x = 10
def test(self):
print(Animal.__x)
pass
class Dog(Animal):
def test(self):
print(Dog.__x)
pass
print(Animal.__dict__)#_Animal__x': 10
print(Animal._Animal__x)#10
用于:数据保护、数据过滤
class Person:
def __init__(self, age):
self.__age = age
p1 = Person(19)
p1.__age = -10
print(p1.__dict__) #{'_Person__age': 19, '__age': -10}
class Person:
def __init__(self, age):
self.__age = age
def setAge(self, age):
if isinstance(age, int) & (100 > age > 0):
self.__age = age
else:
print("input error!")
def getAge(self):
return self.__age
p = Person(10)
p.setAge(20)
p.getAge()#20
xx_: 用于和系统的关键字作以区分,例如class_
__xx__:系统内置写法 如__dict__ __all__
只读属性
概念:一个属性,只能读取,不能写入。
应用场景:有些属性,只限在内部根据不同场景进行修改,对外界来说,只能读取不能修改
比如:电脑类的网速属性,网络状态属性。
class Person:
def __init__(self):#全部隐藏 私有化
self.__age = 18
def getAge(self):
return self.__age#允许只读
#装饰器改进
class Person(object):
def __init__(self):
self.__age = 18
@property #以使用属性的方式来使用这个方法
def age(self):
return self.__age
p = Person()
p.age #18
p.age = 10#AttributeError: can't set attribute
property
作用:将一些属性的操作方法关联到某一个属性之中去。
经典类:没有继承object
新式类:继承了object
python3 默认是新式类
#方式1
class Person(object):
def __init__(self):
self.__age = 18
def get_age(self):
return self.__age
def set_age(self, value):
self.__age = value
age = property(get_age, set_age)
p = Person()
print(p.age)#18
p.age = 20
print(p.age, p.__dict__) #20 {'_Person__age': 20}
#方式2
class Person(object):
def __init__(self):
self.__age = 18
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
self.__age = value
p = Person()
print(p.age)#18
p.age = 100
print(p.age)#100
class Person:
#当我们通过实例,属性= 值来给一个实例添加一个属性,或者修改一个属性值的时候,都会调用
#在方法的内部才会真正的把这个属性和对应的数据存储在__dict__中
def __setattr__(self, key, value):
print(key, value)
if key == "age" and key in self.__dict__.keys():
print("illega")
else:
self.__dict__[key] = value
p = Person()
print(p.__dict__) #{}
p.age = 18
print(p.age, p.__dict__)#18 {'age': 18}
p.age = 999
print(p.age, p.__dict__)#18 {'age': 18}
系统内置属性
类属性
类属性
__dict__:类的属性
__bases__:类的所有父类构成的元组(python支持多继承
__doc__:类的文档字符串
__name__:类名
__module__:类定义所在的模块
实例属性
__dict__:实例的属性
__class__:实例对应的类
class Person:
"""
This is the class person
"""
age = 19
pass
print(Person.__dict__)#{'__module__': '__main__', '__doc__': '\n This is the class person\n ', 'age': 19, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
print(Person.__bases__)#(<class 'object'>,)
print(Person.__doc__)#This is the class person
print(Person.__name__)#Person
print(Person.__module__)#__main__
方法
描述一个目标的行为动作
class Person:
def eat(self):
print(1)
p = Person()
p.eat()
方法的划分
划分依据:方法的第一个参数必须要接收的划分类型
实例方法:第一个参数必须是一个实例
类方法:第一个参数需要接受到一个类
静态方法:第一个参数并不默认接受任何值
三种方法均是存储在类之中的,没有存储在实例之中的。
class Person:
def eat(self):
print("这是实例方法", self)
@classmethod
def classmethod(cls):
print("这是一个类方法", cls)
@staticmethod
def staticmethod():
print("这是一个静态方法")
p = Person()
p.eat()#这是实例方法 <__main__.Person object at 0x000002889F932F10>
Person.classmethod() #这是一个类方法 <class '__main__.Person'>
Person.staticmethod()#这是一个静态方法
p.staticmethod()#这是一个静态方法
Person.eat()#TypeError: eat() missing 1 required positional argument: 'self'
p.classmethod() #这是一个类方法 <class '__main__.Person'>
Person.staticmethod()#这是一个静态方法
p.staticmethod()#这是一个静态方法
调用类中的方法时,要保证不同类型的方法第一个参数接受到的数据,是他们想要的类型。
实例方法
标准调用:不用手动传参数,解释器会自动把调用对象本身传递过来的对象作为参数
其他调用:
类调用
间接调用
本质就是直接找到函数本身来调用
class Person:
def eat(self, food):
print("在吃饭", food, id(self)) #在吃饭 meat 1900029436832
p = Person()
p.eat("meat")
print(id(p))#1900029436832
#类调用
print(Person.eat)
Person.eat(123, "meat")#在吃饭 meat 2310333356208
#间接调用
func = Person.eat
func("123", 999)#在吃饭 999 2310337932464
#一般会将self直接传给方法,即使删除self参数也遵循这样的默认标准
class Person:
def eat(self, food):
print("在吃饭", food, id(self)) #在吃饭 meat 1900029436832
def eat2(xxx):
print(xxx)
p = Person()
p.eat2() #<__main__.Person object at 0x0000022F7F1CD040>
类方法
class Person:
def eat(self, food):
print("在吃饭", food, id(self)) #在吃饭 meat 1900029436832
@classmethod
def leimethod(cls):
print(cls)
Person.leimethod()#<class '__main__.Person'>
p = Person()
#实例会被忽略
p.leimethod()#<class '__main__.Person'>
#子类调用父类的静态方法
#会将子类直接传递给cls
class A(Person):
pass
A.leimethod()#<class '__main__.A'>
静态方法
class Person:
def eat(self, food):
print("在吃饭", food, id(self)) #在吃饭 meat 1900029436832
@classmethod
def leimethod(cls):
print(cls)
@staticmethod
def jinmethod():
print("Hello world")
p = Person()
p.jinmethod()#Hello world
Person.jinmethod()#Hello world
方法对属性的访问权限
class Person:
age = 18
def eat(self):#可以访问对象的属性
print("实例方法")
print(self.age)
print(self.num)
@classmethod#只能访问类属性
def leimethod(cls):
print(cls.age)
@staticmethod #类和实例都无法访问
def jinmethod():
print(Person.age)#18
p = Person()
p.num = 100
#类属性
print(p.age)#18
print(Person.age)#18
#实例属性
print(p.num)#100
p.eat()#实例方法 18 100
Person.leimethod()#18
私有化方法
class Person:
__age = 18
def __run(self):#只能在类定义的内部
print(self.__age)
p = Person()
print(Person.__dict__)#名字重整机制
p.__run()
内置方法
信息格式化操作
__str__
class Person:
def __init__(self):
self.name = "niko"
self.age = 18
def __str__(self):
return "name:%s, age:%d" % (self.name, self.age)
p = Person()
print(p.name)
print(p.age)
print(p)#name:niko, age:18
__repr__
class Person:
def __init__(self):
self.name = "niko"
self.age = 18
def __str__(self):
return "name:%s, age:%d" % (self.name, self.age)
def __repr__(self):
return "hello world"
p = Person()
print(p.name)
print(p.age)
print(repr(p))#hello worlda
元类
概念:创建类对象的类(type类)
num = 10
print(num.__class__)#<class 'int'>
s = "abc"
print(s.__class__)#<class 'str'>
class Person:
pass
print(Person.__class__)#<class 'type'>
print(int.__class__)#<class 'type'>
print(set.__class__)#<class 'type'>()
print(type.__class__)#<class 'type'> 再往上就没了!!!元类是最初的类
补充
类的创建方式
#方式1
class Person:
count = 0
def run(self):
pass
#方式2 使用元类
#第一个参数是类的name 第二个参数是元组,也就是该类的父类 第三个参数是dict
def run(self):
pass
Dog = type("Dog", (), {"name" : "niko", "run" : run})
dog = Dog()
print(dog.name)#niko
dog.run()
类对象先通过自己的属性__metaclass__来指明自己从哪个类对象创建而来
找不到该属性则去找自己的父类的__metaclass__来找自己的 元类
如果还没找到就在模块里面去找,也就是文件中的全局变量区域找有无__metaclass__
如果还没有就会找到type,根据type创建类对象。
__metaclass__ = type
class Person:
__metaclass__ = type#可以是自己定义的类
pass
class Person(metaclass = type):
pass
class Animal:
pass
class Person(Animal):
pass
元类应用场景:
1、拦截类的创建
2、修改类
3、返回修改之后的类
类的描述
方便理清逻辑思路
方便多人合作时候开发时候沟通
方便生成项目文档
class Person:
"""
类的作用、构造函数、类属性的描述
Attributes:
count : int 代表人的数目
"""
count = 1
def run(self, step):
"""
:param step : 参数的含义,类型,是否有默认值
:return : 返回的结果的含义,返回数据的类型
"""
print("hello world")
help(Person)
![](https://img-blog.csdnimg.cn/img_convert/44bab45ae2aabc2bf0bf94010c27ba3e.png)