创建一个初级的类的使用
下面是一个简单的实例:
class Person:
def set_name(self,name):
self.name=name
def get_name(self):
return self.name
def greet(self):
print("Hello ,world I am {}.".format(self.name))
下面是对以上创建的类的使用详情:
wangming=Person()
yangzi=Person()
wangming.set_name("wangming")
yangzi.set_name("yangzi")
wangming.greet()
print(wangming.get_name())
yangzi.greet()
print(yangzi.get_name())
下面是以上代码的执行结果
以上需要注意的是:在执行相关的类的操作的时候,我们应该看到了实际的类的方法中有一个self的参数一直出现。在上面的例子里面,wangming这个类创建之后,使用了其Person的方法,会将wangming这个参数赋值给self,从而来进行函数的调用,当然第一个参数的名字是可以随便取的,但是为了实际的编程方便等原因,默认将第一个参数的名称取名为self
函数与方法的区别
个人见解:认为方法其实是函数的一部分,这是方法限定位只能是函数进行调用,而不能简单的以函数没有像instance.method这样的表达式而方法有instance.method的表达式来进行区分,实际上他们二者的表达式的管理是可以互相区分的,再次需要特别的声明,下面是二者的差异代码:
class Class:
def method(self):
print("this is a method ! ")
def function():
print("this is a function ! ")
instance=Class()
instance.method()
instance.method=function#将instance里面的一个方法直接重新命位一个函数,使得instance.method实际上调用的是一个函数
instance.method()#这里调用的是一个函数而不是一个方法
代码结果:
以上演示了instance.method实际上调用的不是一个方法,而实际上是一个函数的操作,虽然上面运用了函数与方法的重命名的操作,需要注意夫人是上面的操作过程中instance.method=function这段代码,只能这样写,不能在左右表达式两边加上括号,因为这样会导致将返回值重新赋值的操作,与实际的目标不一致,这里只是为了将函数与方法进行重新命名的操作,需要注意!
class Bird:
song="this is a method"
def sing(self):
print(Bird.song)
bird=Bird()
bird.sing()
birdsong=bird.sing#这里将原本看上去是函数的操作,直接改变位一个方法的操作,这样的话直接将原本是函数表达式的birdsong的操作更改了方法
birdsong()#这里调用的是一个方法
代码结果:
私有属性的定义
在python中认为,类的私有属性和私有方法直接以两个下划线即可定义,即以两个下划线打头即可。类的私有属性和私有方法是不能被直接调用的,只能被公有属性和公有方法调用。这成为数据隐藏
class Secretive:
def __inacessible(self):
print("you can nit see me .....")
def accessible(self):
print("the secret message is :")
self.__inacessible()
s=Secretive()
s.accessible()#通过其共有方法访问其私有方法
s.__inacessible()#这里不能直接访问私有方法
代码结果:
上面演示的是函数的私有属性和私有方法只能被共有函数所调用
指定超类(基类)
python中对于继承的操作很简单,直接在定义类的时候将父类计入创建类的括号类即可实现,子类继承父类的私有方法和属性,同时也可以直接创建新的属性和方法
class father:
def init(self):
self.name="father"
def test1(self):
print(self.name)
class son(father):
def init(self):
self.name="son"
test_1=father()
test_1.init()
print(test_1.name)
test_2=son()
test_2.init()
test_2.test1()
下面是执行的结果
可以从上面的代码可以看出,实际的代码实现的过程中子类继承了父类的所有的操作,同时需要创建自己的操作的时候只需像原来创建方法一样即可,没有什么区别,但是需要注意的是在创建与父类相同的方法和属性时会直接覆盖父类的方法和属性,这点需要注意
探讨与父类和子类相关的函数
需要注意的是为了分辨一个类是否位了一个类的子类,可以调用issubclass函数实现,为了确定一个函数的基类,可以使用__base__实现,为了确定一个对象是否是一个类的实例可以使用isinstance实现,需要注意的是instance操作可能会导致不确定的意外,这里不建议使用
下面是具体的实现代码(基于上述上一个小节代码实现):
print(issubclass(son,father))
print(issubclass(father,son))
print(isinstance(test_2,father))
print(father.__bases__)
print(son.__bases__)
多重继承
在实际的操作过程中是存在多重继承的操作的,即为一个class对象继承多个class的操作,则其会继承其所有父类的方法和属性
class Calculator:
def calculate(self,expression):
self.value=eval(expression)
class Talker:
def take(self):
print(self.value)
class Caculator_talker(Calculator,Talker):
pass
test=Caculator_talker()
test.calculate("1+2+3")
test.take()
下面是实际的代码结果:
由上面的代码可以看出实际的继承时,一个对象直接继承了多个父类的方法,并且需要注意到的是,上面的take类中没有value属性,结果也没有报错,这一点需要考虑清楚,同时需要注意到的是在多重继承时,如果出现多个父类同时有一个方法的时候,前一个父类会覆盖掉后一个父类的操作,基上述中如果都具有run这个方法的话,前面的caculator的run会直接覆盖掉子类的run
关于hasattr的使用
hasattr(object, name)
判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。
class hasattr_:
name='wangming'
def init(self):
print(self.name)
t_test=hasattr_()
print(hasattr(t_test,'name'))
print(hasattr(t_test,"init"))
print(hasattr(t_test,"haha"))
下面是执行结果
关于setattr的使用
setattr(object, name, values)
给对象的属性赋值,若属性不存在,先创建再赋值。
class setattr_:
name="WANGMING"
def init_test(self):
print("hallo everyone")
t_setattr=setattr_()
print(setattr(t_setattr,"name",18))#name存在,则直接赋值即可
print(t_setattr.name)
setattr(t_setattr,"test","just a test")#那么不存在,则创建以后再赋值
print(t_setattr.test)
关于getattr的使用
getattr(object, name[,default])
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。
class getattr_:
name="wangming"
def run(self):
return "this is just a test"
t_getattr=getattr_()
print(getattr(t_getattr,"name"))
print(getattr(t_getattr,"run"))
print(getattr(t_getattr,"run")())