社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
属性 | 含义 |
---|---|
_name_ | 类、函数、方法等的名字,要调用实例显示的话要在前加上__class__ |
_class_ | 对象 或 类所属的类名 |
_module_ | 对象或类所属的类 (父) |
_doc_ | 类、函数的文档字符串,如果没有定义则为None (类和实例) |
_dict_ | 类或实例的属性,可写的字典(类和实例) |
mro() 调用方法,类的名字加上.mro() # 可以得到查找循序
例子:
class Myname:
def __init__(self, nam):
self.nam = nam
# __name__和__class__的运用
def show(self):
# print('11', self.__class__.__name__) # __name__ 不能直接通过实例调用
print('44', __class__.__name__) # 少了self实例得到的是类的名字
def show2(self):
print('22', self.__module__) # 类所定义的模块名
# print('55', self.__mro__)
class Car(Myname):
def carshow(self):
print('33', self.__module__) # 类所定义的模块名
b = Car('tom')
print(b.show())
print(b.show2())
print(b.carshow())
print(Car.mro() # 查找循序
方法 | 意义 |
---|---|
_dir_ | 返回类或者对象的所有成员名称列表。dir()函数就是调用 _dir_ ()。 使用实例调用时,如果提供 _dir_ (),则返回其返回值,要求是可迭代对象。 如果没有提供 _dir_() ,则会从实例和类及祖先类中收集信息 |
用法:
dir() 括号里加上 你想查询的对象
如何用dir()函数查看模块属性和方法,例子:
class Animal:
x = 123
def __init__(self, name, age=20, color=10):
self.name = name
self.age = age
self.color = color
def show(self):
pass
print('the dir is {}'.format(dir())) # 在模块中返回模块的属性
print('the dir is {}'.format(dir(Animal))) # 在返回模块的变量名
print(dir([]))
class Person:
def show(self):
a = 100
t = int(a)
print(dir())
def test(a=50, b=100):
print(dir())
Person().show() # 实例的输出:a t self
test() # 只输出变量
方法 | 意义 |
---|---|
_new_ | 实例化一个对象 该方法需要返回一个值,如果该值不是cls的实例,则不会调用 _init_ 该方法永远都是静态方法。等于创建一个类的实例的方法 |
_new_ 方法很少使用,即使创建了该方法,也会使用 return super().__new__(cls) 基类object的 _new_ 方 法来创建实例并返回。
class Persron(object):
def __new__(cls, *args, **kwargs):
print('new')
return super().__new__(cls) #
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return '<Preson {} {} >'.format(self.name, self.age)
if __name__ == '__main__':
pi = Persron('tom', 18)
print(pi) # 缺少str 或者repe 看到的只是一个类对象的实例 <__main__.Persron object at 0x10214fcf8>
方法 | 意义 |
---|---|
__str__ | str()函数、format()函数、print()函数调用,需要返回对象的字符串表达。如果没有定义,就 去调用 __repr__ 方法返回字符串表达,如果 __repr__ 没有定义,就直接返回对象的内存地 址信息 |
__repr__ | 内建函数repr()对一个对象获取字符串表达。调用 __repr__ 方法返回字符串表达,如果 __repr__ 也没有定义,就直接返回object的定义 就是显示内存地址信息 |
__bytes__ | bytes()函数调用,返回一个对象的bytes表达,即返回bytes对象 |
例子:
class C:
def __init__(self, name):
self.name = name
def __bytes__(self): # 二进制转换
# return "{} is {}".format(self.name, self.age).encode()
import json
return json.dumps(self.__dict__).encode()
def __repr__(self): # 装换成字符串输出,没有定义的话,会返回对象的内存地址信息
return '<re:{}>'.format(self.name)
print(C('tom'))
print(bytes(C('123'))) # 二进制装换,成json
方法 | 意义 |
---|---|
_hash_ | 内建函数 hash() 调用的返回值,返回一个整数。如果定义这个方法该类的实例就可hash |
_eq_ | 对应==操作符,判断2个对象是否相等,返回bool值 |
class A:
def __init__(self, name, age=18):
self.name = name
def __hash__(self):
# return 1
return hash(self.name) # 可以调用hash()
def __eq__(self,other):
return self.name == other.name
def __repr__(self):
return self.name
a = A('kenny')
b = A('kenny')
c = A('tom')
print(id(a),id(b),id(c)) # ip地址都不一样
# 内容对比 用到eq
print('1.',a == b)
print('2.',a==c )
print(hash(a),hash(b),hash(c))
print('3.',a is b) # hash地址一样,但是ip地址不一样,所以是False
print({a,b})
# 总结: == 比较的是内容, is 比较的是ip地址, set集合要去重,必须内容和哈希地址一样
set() 集合的内容和****hash值地址一样就去重。有hash冲突并不去重,也不看id地址
练习: 设置一个二维坐标Point 它是可hash类型,并比较2个实例坐标是否相等
from collections import Hashable # 导入hashable判断是否hash类型
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __hash__(self):
# return hash((self.x, self.y))
return 1
def __eq__(self, other):
return self.x == other.x and self.y == other.y
a = Point(4, 5)
b = Point(5, 6)
c = Point(5, 6)
print(a.__hash__(), b.__hash__())
print(a == b)
print(b == c)
print(isinstance(a,Hashable)) #True
方法 | 意义 |
---|---|
__ bool__ | 内建函数bool(),或者对象放在逻辑表达式的位置,调用这个函数返回布尔值。 没有定义 __bool__ (),就找__ len__ ()返回长度,非0为真。如果 __len__ ()也没有定义,那么所有实例都返回真 |
例子:(注意不能通过是否带引号来判断输出值的类型,判断类型还是要选择type或者isinstance)
class B:
def __bool__(self):
return False
print(bool(B)) # 判断有没有存在
print(bool(B())) # 有定义的实例调用为return
class A: pass
class C:
def __len__(self):
return 0
print(bool(A()))
if A():
print('Real A')
print(bool(A))
print(bool(A())) # 没有定义,全部实例返回为真
print(bool(C())) # __bool__没找到默认找__len() 返回长度,非0为真
往往是用面向对象实现的类,需要做大量的运算,而运算符是这种运算在数学上最常见的表达方式。例如,上例中 的对+进行了运算符重载,实现了Point类的二元操作,重新定义为Point + Point。 提供运算符重载,比直接提供加法方法要更加适合该领域内使用者的习惯。
例子:实现A类的2个实例相减
class A:
def __init__(self, name, age):
self.name = name
self.age = age
def __sub__(self, other): # 定义的是-
return self.age - other.age
def __isub__(self, other): # 如果没有定义__isub__,则会调用__sub__
return A(self.name, self - other)
a = A('kek', 18)
b = A('yuyu', 20)
print(a - b)
例子二:我们定义一个“人”的类People,当中有属性姓名name、年龄age。让你需要利用sorted函数对一个People的数组进行排序,排序规则是按照name和age同时排序,即name不同时比较name,相同时比较age。由于People类本身不具有比较功能,所以需要自定义,你可以这么定义People类
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __gt__(self, other):
return self.name > other.name if self.name != other.name else self.age > other.age
def __repr__(self):
return '<{}: {} {}>'.format(__class__.__name__, self.name, self.age)
tom = People('tom', 18)
jenny = People('jenny', 20)
s1 = [1, 4, 2, 5, 123, 3]
for item in sorted([tom, jenny, People('jenny', 28)]):
print(item)
__eq__ 等于可以推断不等于
__gt__ 大于可以推断小于
__ge__ 大于等于可以推断小于等于
也就是用3个方法,就可以把所有比较解决了
方法 | 意义 |
---|---|
__len__ | 内建函数len(),返回对象的长度(>=0的整数),如果把对象当做容器类型看,就如同list 或者dict。bool()函数调用的时候,如果没有 __bool__() 方法,则会看 __len__() 方法 是否存在,存在返回非0为真 |
__iter__ | 迭代容器时,调用,返回一个新的迭代器对象 |
__getitem__ | 实现self[key]访问。序列对象,key接受整数为索引,或者切片。对于set和dict,key为 hashable。key不存在引发KeyError异常 |
__setitem__ | 和 __getitem__ 的访问类似,是设置值的方法 |
例子:构建一个购物车
class Cart:
# 初始化列表
def __init__(self):
self.car = []
# 调用函数,增加
def additem(self, name):
return self.car.append(name)
# 不要返回对象内存地址
def __repr__(self):
return '<{} {}>'.format(__class__.__name__, self.car)
# 判断列表长度
def __len__(self):
return len(self.car)
# 可以迭代
def __iter__(self):
return iter(self.car)
# 返回一个对象可以链式编程
def __add__(self, other):
self.car.append(other)
return self
# 通过索引取到列表的值
def __getitem__(self, index):
return self.car[index]
# 通过索引修改列表的值
def __setitem__(self, index, value):
self.car[index] = value
# return self
# def __contains__(self, index):
# self.car = index
# def
# def __add__(self, other):
cart = Cart()
cart.additem(1)
cart.additem('abc')
cart.additem(3)
print(cart.car)
# 长度、bool
print(len(cart))
print(bool(cart))
# # 迭代
for x in cart:
print(x, end=' ')
# # in
print()
print(3 in cart)
print(2 in cart)
# # 链式编程实现加法
print(cart + 4 + 5 + 6)
print(cart.__add__(17).__add__(18))
# 索引操作
print(cart[1])
cart[1] = 'xyz'
python 中一切皆对象
__call__,类中定义一个该方法,实例可以像函数一样使用
例子:
def foo():
print(foo.__module__, foo.__name__) # 类的名字,函数的名字
foo()
foo.__call__() # 函数即对象,对象foo加上() ,就是调用函数对象call__() 方法
练习:
定义一个类,并实例化得到其实例,像实例函数一样去调用。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __call__(self, *args, **kwargs):
return self
def __repr__(self):
return '<{},{},{}>'.format(self.__class__.__name__, self.name, self.age)
c1 = Person('tom', 12)
print(c1())
class add:
## 不初始化对象
# def __call__(self, *args, **kwargs):
# ret = 0
# for x in args:
# print(x)
# ret += x
# self.ret = ret
# return ret
# 初始化对象
def __init__(self, *args):
self.args = args
def __call__(self, *args, **kwargs):
ret = 0
for i in args:
ret += i
return ret
adder = add()
print(adder(4, 6))
# print(adder.ret)
## 2. 定义一个斐波那契数列,计算第n项[0、1、1、2、3、5、8、13、21]
# [0、1、1、2、3、5、8、13、21]
# 普通方法
a = 1
b = 0
for i in range(6):
a, b = b, a + b
print(b)
# 函数,生成器 做成生成器函数
def fib():
a = 1
b = 0
while True:
a, b = b, a + b
yield a
foo = fib()
for i in range(10):
print(next(foo))
# 递归
def fib(n):return n if n <= 1 else fib(n - 2) + fib(n - 1)
#做成一个类:
class Fib:
def __init__(self):
self.x = 1
self.y = 1
def __call__(self, index):
if index <= 1:
return index
else:
for i in range(index - 2):
self.x, self.y = self.y, self.x + self.y
return self.y
fib = Fib()
print(fib(5))
# 如何提高效率,一是使用cache缓存,二是将类做成一个列表,
# 一 缓存
import functools
@functools.lru_cache()
def fib(n):
return n if n <= 1 else fib(n - 2) + fib(n - 1)
print(fib(135))
# 二 类的列表 实现,长度,可索引,可迭代,可实例调用
class Fib:
def __init__(self):
self.lb = [0, 1, 1]
def __call__(self, index):
if index < len(self.lb):
return self.lb[index]
for i in range(3, index+1):
self.lb.append(self.lb[i - 2] + self.lb[i - 1])
return self.lb
fib = Fib()
print(fib(3))
class Fib:
def __init__(self):
self.arrlis = [0, 1, 1]
def __call__(self, index):
if index < len(self.arrlis):
return self.arrlis[index]
for i in range(3
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/a13532865022/article/details/90453408
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!