提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
学习内容 :方法相关
方法相关
一、方法的概念
描述一个目标的行为动作,目标可以是类,可以是对象
class Person:
def eat2(self):
print(1)
p = Person()
p.eat2()
1.方法的划分
实例方法,类方法,静态方法
(1)划分依据是:方法的第一个参数必须要接收的数据类型
实例方法默认第一个参数要接收到一个实例
类方法默认第一个参数要接收到一个类
静态方法啥也不默认接收
(2)三种方法的写法
class Person:
def eat2(self): # 实例方法
print("这是一个实例方法")
@classmethod
def leifangfa(cls): # 类方法
print("这是一个类方法")
@staticmethod
def jingtaifangfa():
print("这是一个静态方法")
(3)不管是哪种类型的方法,都是存储在类当中,没有在实例当中的
二、实例方法,类方法,静态方法的语法及调用
1.实例方法
class Person:
def eat(self, food):
print("在吃饭,",food)
p = Person()
p.eat("土豆") #标准调用方法
2.类方法
class Person:
@classmethod
def leifangfa(cls, a):
print("这是一个类方法", a)
Person.leifangfa(123) # 调用方法1
p = Person()
p.leifangfa(666) # 调用方法2
#继承,子类
class A(Person):
pass
A.leifangfa(0)
3.静态方法
class Person:
@staticmethod
def jingtai():
print("这是一个静态方法")
Person.jingtai() # 调用方法1
p = Person() # 调用方法2
p.jingtai()
4.不同类型的方法中访问不同类型属性的权限问题
三.补充
1.类相关补充
(1)元类
(1)元类:创建类对象的类 type(元类)
print(int.__class__)
(2)类对象的创建流程(利用元类)
def run(self):
print(self)
Dog = type("Dog", (), {"count": 0, "run": run})
(3)元类的查找机制
a.先检测类中是否有明确__metaclass__属性
b.检测父类中是否存在__metaclass__属性
c.检测模块中是否存在__metaclass__属性
d.通过内置的type这个元类,来创建这个类对象
class Person:
__metaclass__ = xxx
pass
(2)类的描述(注释)
三个双引号对来描述
查看类的文档:
help(Person)
(3)项目注释文档的生成
(1)方式1:使用内置模块 pydoc 进入terminal
查看文档描述 -m pydoc 模块名称
启动本地服务,浏览文档 -m pydoc -p 6666(端口号ip)
生成指定模块html文件 -m pydoc -w 模块名称
2.属性相关补充
python并没有真正的私有化支持,但可以使用下划线完成伪私有的效果
类属性和实例属性遵循相同的规则
(1)公有属性
(2)受保护属性 _x
(3)私有属性 __x
名字重整机制 _类名__x
(1)私有属性应用场景
初始化方法:
class Person:
# 主要作用:当我们创建好一个实例对象之后,会自动的调用这个方法,
# 来初始化这个对象
def __init__(self):
self.age = 18
(4)只读属性
概念:一个属性,一般指实例属性,只能读取,不能写入
1.方式1:私有化操作全部隐藏,把读的操作公开
class Person(object):
def __init__(self):
self.__age = 18
# @property主要作用是,可以以使用属性的方式,来使用这个方法
@property
def age(self):
return self.__age
p1 = Person()
p1.age
2.方式2
class Person:
# 当我们通过 实例.属性 = 值,给一个实例增加一个属性或者修改属性的时候
# 都会自动调用__setattr__这个方法, 在这个方法内部,
# 才会真正的把属性key以及对应的数值value,存储到__dict__里面
def __setattr__(self, key, valule):
print(key,value)
# 1.判断key是否是我们要设置的只读属性的名称
if key == "age" and key in self.__dict__.keys():
print("这个属性是只读属性,不能设置数据")
# 2.如果不是只读属性的名称,则真正的给它添加到这个实例里面去
else:
self.__dict__[key] = value
p1 = Person()
p1.age = 18
经典类和新式类
经典类:没有继承(object)
新式类:继承(object)
python3定义一个类时,默认继承(object)
查看基类代码:
类名.__bases__
(5)property在新式类中的使用
第一种使用方式
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)
p1 = Person()
p1.age
第二种使用方式
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
(6)常用内置属性
3.方法相关补充
(1)私有化方法
class Person:
__age = 18
def __run(self):
print("pao")
p = Person()
p.__run() ##会报错 已经变成了_Person__run
(2)内置特殊方法
1.信息格式化操作
__str__方法
__repr__方法
class Person:
def __init__(self, n, a):
self.name = n
self.age = a
def __str__(self):
return "姓名%s, 年龄%s"%(self.name, self.age)
def __repr__(self):
p1 = Person("sz", 18)
p2 = Person("zhangsna", 19)
print(p1) # 姓名sz,年龄18
print(repr(p1)) ##<__mian__.Person boject at 0x000000.....>
这两个方法都是通过字符串描述对象,str方法面向用户,repr面向开发人员
2.调用操作
__call__方法 :作用:使得对象具备当做函数,来调用的能力
class Person:
def __call__(self, *args, *kwargs):
print("xxx")
pass
p = person()
p() #输出xxx
应用实例:
class PenFactory:
def __init__(self, p_type)
self.p_type = p_type
def __call__(self,p_color)
print("画笔类型%s,它是%s颜色"%(self.p_type, p_color))
gangbiF = PenFactory("钢笔")
gangbiF("红色")
gangbiF("黄色")
qianbiF = PenFactory("铅笔")
3.索引操作
作用:可以对一个实例对象进行索引操作 增查删
步骤:1.实现三个内置方法2.可以以索引的形式操作对象
class Person:
def __init__(self):
self.cache = {}
def __setitem__(self, key, value):
self.cache[key] = value
def __getitme(self, item):
return self.cache[item]
def __delitem__(self, key):
del self.cache[key]
p = Person()
p["name"] = "sz" #增操作
print(p["name"]) #查操作
del p["name"] #删操作
4.切片操作
可以对一个实例对象进行切片操作 slice对象
class Person:
def __init__(self):
self.items = [1,2,3,4,5,6,7,8]
def __setitem__(self, key, value):
self.items[key] = value
def __getitme(self, item):
return self.items[item]
def __delitem__(self, key):
del self.items[key]
p = Person()
p[0: 4: 2] = ["a", "b"]
5.比较操作
作用:可以自定义对象“比较大小,相等以及真假”规则
class Person:
def __init__(self, age,height):
self.age = age
self.height = height
def __eq__(self,other): #用 == 调用
return self.age == other.age
def __ne__(self,other): #用 !=调用
return self.age != other.age
def __gt__(self,other): #大于
pass
def __ge__(self, other): #大于等于
pass
def __lt__(self, other): #小于
pass
def __le__(self, other): #小于等于
pass
pass
p1 = Person(18, 180)
p2 = Person(17,190)
print(p1 == p2) # True
补充方法
import functools
@functools.total_ordering #帮助自动补全方法
calss Person():
def __lt__(self, other)
pass
6.迭代器(遍历操作)iter:将一个对象转换成为迭代器使用
方式一:
class Person:
def __getitem__(self, item):
return 1
pass
p = Person()
for i in p:
print(i) #1 1 1 1
方式二iter 优先级高于__getitem__
class Person:
def __iter__(self):
return self #要返回一个迭代器
def __next__(self): #把self变成可迭代的
return 1
pass
p = Person()
#查看p是不是迭代器
import collections
print(ininstance(p, collections.Iterator)) #True
for i in p:
print(i) #1 1 1 1
一个可迭代对象,肯定可以用for in
但是可以用for in的 不一定是可迭代对象
7.描述器
可以描述一个属性操作的对象
定义方式1:property
class Person:
def __init__(self):
self.__age = 10
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if value < 0:
value = 0
self.__age = value
@age.deleter
def age(self):
del self.__age
#age = property(get_age, set_age, del_age)
p = Person()
print(p.age)
定义方式2:
写一个描述器,接管对象的增删改查操作
#资料描述器 get set
#非资料描述器 仅仅实现了get方法,那么它就是一个非资料描述器
#资料描述器 > 实例属性 >非资料描述器
class Age:
def __get__(self, instance, owner):
return instance.v
def __set__(self, instance, value):
instance.v = value
def __delete__(self, instance):
print("delete")
class Person:
age = Age()
####8.使用类,实现装饰器
class check:
def __init__(self,func):
self.f = func
def __call__(self, *args, **kwargs):
print("登陆验证")
self.f()
@check
def fashuoshuo():
print("发说说")
fashuoshuo()