类是封装对象的属性和行为的载体,具有相同属性和行为的实体被称为类;这是一个抽象的概念。对象就是把一个抽象的类进行了具体化,具体化的结果叫对象,这个过程叫实例化。
class 后面紧跟类名,即 Person,类名通常大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用 object 类,这是所有类最终都会继承的类。在类中我定义了一个MyName() method(方法)。
class People(object):
def __init__(self,name,site) -> None:
self.name = name
self.site = site
def MyName(self):
print("My name is {} and my site is {}".format(self.name,self.site))
Ann = People('Ann',1)
Ann.MyName()
这里的Ann是People()类的实例,也是一个对象。
**_init_()**是一个特殊方法,类创建时会自动执行它,它必须包含一个self参数且该参数位于第一个;self参数指向实例本身的引用,用于访问类中的属性和方法。方法在调用是自动传递实际参数self。
注意:
(1) 、__init__方法的第一参数永远是self,表示创建的类实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
(2)、有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器会自己把实例变量传进去:
class Test:
def ppr(self):
print(self)
print(self.__class__)
t = Test()
t.ppr()
执行结果:
<__main__.Test object at 0x000000000284E080>
<class '__main__.Test'>
从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__则指向类。
注意:把self换成this,结果也一样,但Python中最好用约定俗成的self。
在Python解释器的内部,当我们调用t.ppr()时,实际上Python解释成Test.ppr(t),也就是把self替换成了类的实例。
class Test:
def ppr():
print(self)
t = Test()
t.ppr()
代码结果:
Traceback (most recent call last):
File "cl.py", line 6, in <module>
t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given
运行时提醒错误如下:ppr在定义时没有参数,但是我们运行时强行传了一个参数。由于上面解释过了t.ppr()等同于Test.ppr(t),所以程序提醒我们多传了一个参数t。这里实际上已经部分说明了self在定义时不可以省略。当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。
class Test:
def ppr():
print(__class__)
Test.ppr()
运行结果:
<class '__main__.Test'>
class Parent:
def pprt(self):
print(self)
class Child(Parent):
def cprt(self):
print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()
运行结果:
<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt©,所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。
Python并没有对方法和属性的访问权限进行限制;可以方法或属性前面加单下划线、双下划线,可以在首尾加双下划线:
首尾双下划线表示定义特殊方法,一般是系统定义名字。如:
__init__
以单下划线开头的表示protected(保护)类型的成员,只允许类本身和子类进行访问,但不能使用“from module import ”语句导入。
class Swan:
_neck_swan='天鹅类' # 保护属性
def __init__(self):
print("__init__():",Swan._neck_swan) # 在实例方法中访问保护属性
swan=Swan() # 创建Swan实例
print("直接访问:",Swan._neck_swan) #保护属性可以通过类名访问
print("直接访问:",swan._neck_swan) #保护属性可以通过实例名访问
双下划线表示private(私有)类型成员,只允许定义该方法的类本身进行访问,而且不能通过类的实例进行访问,但是可以通过“类的实例名.__类名__xxx”方式访问
class Swan:
__neck_swan='天鹅类' # 私有属性
def __init__(self):
print("__init__():",Swan.__neck_swan) # 在实例方法中访问私有属性
swan=Swan() # 创建Swan实例
print("加入类名:",swan._Swan__neck_swan) # 私有属性可以通过“类的实例名._类名__xxx”方式访问
print("直接访问:",swan.__neck_swan) # 私有不能属性可以通过实例名访问,会报错