#Python学习笔记(day8)——类及对象
类是图纸,对象是房屋;类是工厂,对象是产品
类是面向对象编程的语言的一个显著特点,对象的静态行为称作属性,对象的动态行为称作方法。
虽然同一个类可以创造出许多个实例化对象,但是这些实例化对象并不相同。实例化对象可以通过方法中的隐形参数self传入,以此达到模样相同,实质不同的效果。
Python中变量的访问属性。
Python中的私有是伪私有,通过在定义时需要私有的变量或者方法前加“__“即可。实际上,Python会默认这个符号是一个改名操作。通过实例对象进行访问的时候,他们的名字更改为 :对象名._类名__方法名/属性名
类的继承
Python中的继承只需要在子类定义时指明需要继承的父类即可。继承是一个继续施工和改造的过程。
子类可能会出现定义与父类同名的函数或者变量造成覆盖的现象,如果想引用父类同名变量的话可以通过方法super().变量名/方法名。该方法可以根据你的父类调用相应的函数。这个方法比实用类对象方法的优势在于,此处在多线程继承关系中,若需要调整继承关系只需要修改括号内的继承关系,无需在类定义内部修改。
关于类的bif:
1、hasattr() 验证实例对象是否为属于某个类
hasattr(obj, name, /)
Return whether the object has an attribute with the given name.
2、getattr() 访问某个实例对象的属性
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
3、setattr() 设置指定属性的值或者创建一个特定的属性
setattr(obj, name, value, /)
Sets the named attribute on the given object to the specified value
setattr(x, 'y', v) is equivalent to ``x.y = v''
4、issubclass()检测一个类是否为另一个类的子类,若后面是个由类组成的元组,就是检测这个类是否在这个元组里有父类
issubclass(cls, class_or_tuple, /)
Return whether 'cls' is a derived from another class or is the same class.
A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to
check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)
or ...`` etc.
5、delattr() 删除一个属性
delattr(obj, name, /)
Deletes the named attribute from the given object.
delattr(x, 'y') is equivalent to ``del x.y''
__init__是类属性中的一个方法,它可以在类创建对象的时候进行初始化操作。
类的魔法方法:
1、__new__:
和 __init__ 的区别就在于, __new__返回一个实例对象,而__init__是对这个实例对象进行操作。如果返回的这个实例对象是不可变类型(自从生成之后便在该内存上固定,无法对该地址上的值进行修改),比如str、int、tumple,则__init__无法对该实例对象进行修改(比如str都大写啊etc)。所以想要创建一个类CapStr,使得输入的字符串都变成大写,应该对CapStr的__new__进行重写。
2、__del__:
del是默认被调用,是Python垃圾回收机制中最后一环。当一个对象的所有标签被删除之后,该方法便被自动调用来清除这个对象。而del删除的都是对象的标签,并不会删除该地址中储存的内容。
3、__getattr__:
在访问的变量不存在时自动被调用,可定义用户试图访问一个不存在变量时的行为
4、__getattribute__:
访问一个变量时默认被调用,可定义该类属性被访问时的行为,返回这个变量的值。重写该方法时容易陷入死循环的陷阱,因为返回值时
class A :
def __init__(self):
self.x = 0
def __getattribute__(self,name):
print('__getattribute__已被调用')
return super().__getattribute__(name)
def getX(self):
return 0
经代码验证,返回一个值时自动调用该方法,倘若要返回一个属性,则该方法将被迭代调用,即调用两次
因此,这就不难解释在重写__getattribute__方法时,为何容易陷入递归陷阱。将代码改为
def __getattribute__(self,name):
print('__getattribute__已被调用')
return self.name
此时,将会出现迭代器炸裂的情况
5、__setattr__(self, name, value):
当给类属性赋值时会被自动调用,可定义一个类属性被设置时的行为,同样的重写该函数也容易陷入迭代陷阱。
譬如return self.name = value时,这本身就是一个赋值语句,所以自然又会调用该函数陷入无限循环
6、__delattr__(self, name):
定义一个类被删除时的行为
7、私人定制运算符:
譬如:
class new_int(int):
def __add__(self,other):
return int.__sub__(self,other)
self指自身,other指相加运算的另一个参数
Q:
1、super中MRO机制
2、类方法和静态方法的区别
实例方法是对实例进行的动态操作,如修改其中的属性;而类方法则是针对类进行的动态操作,可以对类属性进行更改
而静态方法则无法访问类属性和实例属性,因为既没有传入实例对象self,也没有传入类对象cls
3、描述方法的用途
4、自己定制一个列表为什么要对__len__进行修改??可变列表和不可变列表的区别是什么?不可变列表的值仍可以修改啊