date: 2019-09-10
我使用的Python版本为3.7,没有装配环境的同学可以到下方链接查看教程。
这期开始学习Python的面向对象编程
class Person(object):
pass
其中括号内的object
表示继承自object
类,暂时不用理会,照着写就行(先提一句,Python类似C++的支持多重继承,而非像Java一样使用接口)
实例化一个对象都离不开初始化这一步。与C++类似,类的方法也具有类似this
的属性。不过Python中必须时显示定义在参数列表的第一个其名字可以随意更改,但我们约定俗成为self
,当然在调用时并不需要显式传入
class Person(object):
def __init__(self, name):
self.name = name
p = Person("ABC")
由于Python是动态语言,所以我们不会先在类内定义好各种属性,而是通过各种方式绑定。
一种方法是直接绑定:
class Person(object):
def __init__(self, name):
self.name = name
p = Person("ABC")
p.address = "Earth"
另一种是初始化时传递,我们需要用到**kw
:
class Person(object):
def __init__(self, name, **kw):
self.name = name
for k, v in kw.iteritems():
setattr(self, k, v)
p = Person("ABC", address = "Earth")
其中setattr
函数传入三个参数:对象本身、属性名、属性值
Python中没有类似C++的private
等访问限制符,而是通过名字来确定:双下划线(__)开头的属性为私有属性,外部无法访问
class Person(object):
def __init__(self, name, address):
self.name = name
self.__address = address
p = Person("ABC", "aaa")
如果尝试访问p.__address
,则会报错
在Python中,其实对象的方法也是属性,它的值是一个函数对象。当然,它与一般的函数不同,可以在调用时隐式传递一个对象,并且可以通过它来访问对象的私有属性
def myAddress():
return "Earth"
class Person(object):
def __init__(self, name):
self.name = name
p = Person("ABC")
p.getAddress = myAddress
print(p.getAddress())
# Earth
的确可以成功调用,但如上面所说,p.getAddress
并不能访问p
的私有属性(此处不演示了)
我们可以通过typs
中的MethodType
函数来将函数转换为方法:
def myAddress(self):
return "Earth"
class Person(object):
def __init__(self, name):
self.name = name
import types
p = Person("ABC")
p.getAddress = types.MethodType(myAddress, p)
print(p.getAddress())
# Earth
需要注意的一点是,转换的函数第一个参数会变成self
(并不一定叫self
,而是第一个参数会被当成self
),所以在定义的时候就应该留好位置。
这种绑定法可以避免在多个类中写相同的方法,只需要写一遍然后绑定多次即可。
类似C++中的类内的静态属性,Python同样具有类似的属性
class Person(object):
address = "Earth"
def __init__(self, name):
self.name = name
p = Person("ABC")
print(p.address)
# Earth
print(Person.address)
# Earth
既可以通过对象来访问,也可以直接通过类名来访问,同样的也根据名字来确定访问权限。如果对象的属性与类的属性名一致时,通过对象来访问时类的属性会被屏蔽,即调用p.address
会先检查p
有没有address
属性,如果有就直接调用它的值,没有时才会再访问Person.address
。
至于类的方法,由于类内定义的默认为实例方法,即只能通过对象来调用,所以我们需要通过装饰器来让它变成类的方法,这个方法也会被对象的同名方法屏蔽
class Person(object):
@classmethod
def getAddress(cls):
return "Earth"
def __init__(self, name):
self.name = name
p = Person("ABC")
print(p.getAddress())
# Earth
同样,在定义时第一个参数留给了cls
,这也是一个约定俗成的变量名,表示这个类,它跟self
一样,在调用时不需要传入。
原文:https://www.cnblogs.com/wilfredshen/p/12853900.html