赞
踩
Python 的类内置了一些通用的属性和方法,方便我们进行操作和对类的管理。我们可以使用dir(ClassName)来查看这些属性和方法,其中前后双下划线的如__dir__就是内置的。
__doc__ 可以返回类的介绍,这个介绍是我们之前在定义类时写的注释,帮助我们记住类的作用和使用方法,也可以写一些使用例子,我们接触三方库时,可以通过它查看它的介绍。
tom = Student('tome')
tom.__doc__
# '这是一个学生类'
new 和 init 在类在实例化过程中都会被调用的方法,会先调用 new 函数再调用 init 函数。 __new__ 会创建对象,相当于构造器,起创建一个类实例的作用,__init__ 作为初始化器,负责对象的初始化。
new 的第一个参数是 cls 是类自身,init 是 self,是实例。一般情况下,我们很少需要自己编写 new,只需要关注 init 实例初始化。
new 是静态函数,init 是实例函数。如果,new 函数不返回实例对象,那么 init 函数就不会被调用:
class A(object):
def __new__(cls):
print("A.__new__ called")
# return super().__new__(cls)
def __init__(self):
print("A.__init__ called")
s = A()
print(s)
# A.__new__ called
# None
另外 init 函数只能返回 None,否则会引起 TypeError。
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
#!/usr/bin/python3
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 输出结果:3.0 -4.5
类的方法与普通的函数只有一个特别的区别——第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x100771878>
__main__.Test
从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。
__call__ 可以让实例对象像函数那样可被执行,callable(lily) 默认是不能被执行的,我们重写 call 。
class Student(object): def __init__(self, a, b): self.name = a self.age = b super(Student, self).__init__() def __call__(self): self.age += 1 print('我能执行了') # 实例化 lily = Student('lily', 18) callable(lily) # True lily() # 我能执行了 lily.age # 19
我们先定义一个Student类,打印一个实例:
>>> class Student(object):
... def __init__(self, name):
... self.name = name
...
>>> print(Student('Michael'))
<__main__.Student object at 0x109afb190>
打印出一堆<main.Student object at 0x109afb190>,不好看。
怎么才能打印得好看呢?只需要定义好__str__()方法,返回一个好看的字符串就可以了:
>>> class Student(object):
... def __init__(self, name):
... self.name = name
... def __str__(self):
... return 'Student object (name: %s)' % self.name
...
>>> print(Student('Michael'))
Student object (name: Michael)
但是直接敲变量不用print,打印出来的实例还是不好看:
>>> s = Student('Michael')
>>> s
<__main__.Student object at 0x109afb310>
这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
解决办法是再定义一个__repr__()。但是通常__str__()和__repr__()代码都是一样的,所以,有个偷懒的写法:
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__
如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个 __iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的 __next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1 # 初始化两个计数器a,b
def __iter__(self):
return self # 实例本身就是迭代对象,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b # 计算下一个值
if self.a > 100000: # 退出循环的条件
raise StopIteration()
return self.a # 返回下一个值
调用:
>>> for n in Fib():
... print(n)
# 在Python中有自动的垃圾回收机制,它会自动将这些没有被引用的对象删除, # 所以我们不用手动处理垃圾回收 class A: def __init__(self): self.name = 'A类' # del是一个特殊方法,它会在对象被垃圾回收前调用 def __del__(self): print('A()对象被删除了~~~',self) a = A() b = a # 又使用一个变量b,来引用a对应的对象 print(a.name) # a = None # 将a设置为了None,此时没有任何的变量对A()对象进行引用,它就是变成了垃圾 # b = None # del a # del b input('回车键退出...')
# object.__add__(self, other) # object.__sub__(self, other) # object.__mul__(self, other) # object.__matmul__(self, other) # object.__truediv__(self, other) # object.__floordiv__(self, other) # object.__mod__(self, other) # object.__divmod__(self, other) # object.__pow__(self, other[, modulo]) # object.__lshift__(self, other) # object.__rshift__(self, other) # object.__and__(self, other) # object.__xor__(self, other) # object.__or__(self, other) # object.__lt__(self, other) 小于 < # object.__le__(self, other) 小于等于 <= # object.__eq__(self, other) 等于 == # object.__ne__(self, other) 不等于 != # object.__gt__(self, other) 大于 > # object.__ge__(self, other) 大于等于 >=
# inside class Card : # 在 Card 类 内 部: def __lt__ ( self , other ) : # check the suits # 判 断 花 色 if self.suit < other.suit : return True if self.suit > other.suit : return False # suits are the same ... check ranks # 花 色 相 同 ... 判 断 等 级 return self.rank < other.rank # __gt__会在对象做大于比较的时候调用,该方法的返回值将会作为比较的结果 # 他需要两个参数,一个self表示当前对象,other表示和当前对象比较的对象 # self > other def __gt__(self , other): return self.age > other.age # print(p1 > p2) # print(p2 > p1)
# object.__bool__(self)
# 可以通过bool来指定对象转换为布尔值的情况
def __bool__(self):
return self.age > 17
类还有以下方法:
# 类名称的字符
Student.__name__
# 'Student'
# 定义一个类 class A(object): # 类属性 # 实例属性 # 类方法 # 实例方法 # 静态方法 # 类属性,直接在类中定义的属性是类属性 # 类属性可以通过类或类的实例访问到 # 但是类属性只能通过类对象来修改,无法通过实例对象修改 count = 0 def __init__(self): # 实例属性,通过实例对象添加的属性属于实例属性 # 实例属性只能通过实例对象来访问和修改,类对象无法访问修改 self.name = '孙悟空' # 实例方法 # 在类中定义,以self为第一个参数的方法都是实例方法 # 实例方法在调用时,Python会将调用对象作为self传入 # 实例方法可以通过实例和类去调用 # 当通过实例调用时,会自动将当前调用对象作为self传入 # 当通过类调用时,不会自动传递self,此时我们必须手动传递self def test(self): print('这是test方法~~~ ' , self) # 类方法 # 在类内部使用 @classmethod 来修饰的方法属于类方法 # 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象 # 类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls # 类方法可以通过类去调用,也可以通过实例调用,没有区别 @classmethod def test_2(cls): print('这是test_2方法,他是一个类方法~~~ ',cls) print(cls.count) # 静态方法 # 在类中使用 @staticmethod 来修饰的方法属于静态方法 # 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用 # 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数 # 静态方法一般都是一些工具方法,和当前类无关 @staticmethod def test_3(): print('test_3执行了~~~') a = A() # 实例属性,通过实例对象添加的属性属于实例属性 # a.count = 10 # A.count = 100 # print('A ,',A.count) # print('a ,',a.count) # print('A ,',A.name) # print('a ,',a.name) # a.test() 等价于 A.test(a) # A.test_2() 等价于 a.test_2() A.test_3() a.test_3()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。