python 基类方法,Python-类方法

运算符重载

python的运算符重载与c++有很大区别,只需要重写以“__”开头和结尾的特殊方法即可,其常见的运算符重载方法如下:

393a4f056af8?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

运算时以运算符左边的类方法为先,若没有,考虑右边的反向运算方法

就地方法是类似“ += ”的形式

class Vector2D:

def __init__(self, x, y):

self.x = x

self.y = y

def __add__(self, other):

x = self.x + other.x

y = self.y + other.y

return Vector2D(x, y)

def __str__(self):

return "Vector2D(x={},y={})".format(self.x,self.y)

def __sub__(self, other):

return Vector2D(self.x - other.x, self.y - other.y)

v1 = Vector2D(2, 3)

v2 = Vector2D(4, 5)

print(v1+v2)

print(v1-v2)

>>>

Vector2D(x=6,y=8)

Vector2D(x=-2,y=-2)

__str__ 和 __repr__

一般直接打印对象返回的是对象的内存地址,通过_str或_repr,打印类的对象时均会自动执行该方法并打印return的数据。通过对该方法的定义,可以修改打印类对象的结果

两个方法的区别在于:

同时存在时,优先__str__ ,其次__repr__

__str__ 为了让人读,__repr__ 为了让机器读,可结合eval使用

__str__ 由print和str()函数调用,__repr__ 由repr()调用

class Student:

def __init__(self, name):

self.name = name

def __str__(self):

print("111111")

return "name:%s" % self.name

def __repr__(self):

print("22222222")

return "Student(%r)" % self.name

s = Student("张三")

print(s)

# 优先__str__,其次__repr__

# __str__为了让人读,__repr__为了让机器读,可结合eval使用

# __str__由print和str()函数调用,__repr__由repr()调用

str1 = repr(s)

print(str1)

>>>

__str__

name:lisi,age:44,

__dict__

类的__dict__里的存有类的静态函数、类函数、普通函数、全局变量以及一些内置的属性

对象的__dict__中存储了一些self.xxx的一些东西

class User:

num=111111

def __init__(self,name,age):

self.name=name

self.__age=age

def FFFFFFFF(self):

pass

u2 = User('zhangsan',21)

print(User.__dict__)

print(u2.__dict__)

>>>

{'__module__': '__main__', 'num': 111111, '__init__': , 'FFFFFFFF': , '__dict__': , '__weakref__': , '__doc__': None}

{'name': 'zhangsan', '_User__age': 21}

序列

__getitem__ (self, item): 需要返回键 item对应的值

__setitem__ (self,key,value): 需要设置给定键 key的值 value

__delitem__ (self,key): 删除给定键对应的元素。

__len__ (self): 需要返回元素的数量

只要实现了__getitem__ 和 __len__ 方法,就可以认为是序列,可以进行引索、切片等操作

class Puke:

def __init__(self):

self.num = [1, 2, 3, 4, 5, 6, 7, 8]

def __len__(self):

print("L")

return len(self.num)

def __getitem__(self, item):

return self.num[item]

k = Puke()

for x in k:

print(x, end=" ")

print("\n", k[3])

print(k[3:5])

print(k[::-1])

>>>

1 2 3 4 5 6 7 8

4

[4, 5]

[8, 7, 6, 5, 4, 3, 2, 1]

__slots__

Python允许我们在程序运行的过程中动态给class加上属性,但当我们在class中定义一个特殊的__slots__变量,便可以限制该class能添加的属性

使用__slots__要注意,__slot__定义的属性仅对当前类起作用,对继承的子类不起作用

但若在子类中也定义__slots__ ,子类允许定义的属性就是自身的__slots__加上父类的 __slots__

class Student:

__slots__ = ('name','age')

s = Student()

s.name = "zhangsan"

s.age = 20

s.score = 50

>>>

AttributeError: 'Student' object has no attribute 'score'

属性拦截器

__getattribute__(self, item): 当一个类的属性被实例访问时,会自动调用该方法。

当实例调用属性时,比如s1.name,会把name作为实参传进__getattribute__方法中,经过一系列操作后,再把name处理后的结果返回。Python中只要定义了继承object的类,就默认存在属性拦截器,只不过是拦截后没有进行任何操作,而是直接返回。所以我们可以自己改写__getattribute__方法来实现相关功能,比如查看权限、打印log日志等

与__getattribute__功能接近的,还有:

__getattr__(self, key): 在访问对象的key属性的时候,如果对象并没有这个相应的属性,方法,那么将会调用这个方法来处理

__setattr__(self, key, value): 当试图给对象的key属性赋值的时候将会被调用

class Cache:

_cache = dict()

def __setattr__(self, key, value):

if not Cache._cache.keys().__contains__(key):

Cache._cache[key] = []

Cache._cache[key].append(value)

print("__setattr__")

def __getattribute__(self, item):

print("__getattribute__")

if not Cache._cache.keys().__contains__(item):

return None

return Cache._cache[item]

c = Cache()

print(c.user)

print("1111111")

c.user = "zhangsan"

print("2222222")

print(c.user)

>>>

__getattribute__

None

1111111

__setattr__

2222222

__getattribute__

['zhangsan']

描述符

描述符可以用来访问另一个类的属性,定义了以下三种方法的一个或多个的类就可以称为描述符:

__ge__(): 调用一个属性时触发。

__set__(): 为一个属性赋值时触发

__delete__(): 采用del删除属性时触发

其中实现了__get__()和__set__()的描述符,成为数据描述符

实现了__get__()的描述符,成为非数据描述符

访问对象属性的时候:obj.attr一般会先调用__getattribute__(),查找顺序如下:

(1)数据描述符 (2)__dict__属性 (3)非数据描述符

class RevealAccess:

def __init__(self,initval = None,name = "var"):

self.val = initval

self.name = name

def __get__(self, instance, owner):

print("获取..",self.name)

return self.val

def __set__(self, instance, value):

print("设置值:",self.name)

self.val = value

class MyClass:

x = RevealAccess(10,"ver 'x'")

m = MyClass()

m.x

print("111111111")

m.x = 5

>>>

获取.. ver 'x'

111111111

设置值: ver 'x'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值