day 08

python 面向对象编程

1. 类的 __new__() 方法

 定义一个类时,可以用__init__函数来设置类具有的属性,但实际上最先执行的是 __new__ 函数,通过该函数,返回一个

类的实例,这也是为什么init函数有self参数的原因。

class Animal(object):
    def __new__(cls,*args,**kw):
        return   Animal.__new__(cls,*args,**kw)
2. 类的 __del__方法

在该对象被销毁时自动调用__del__方法,可重写print试试。但是实际上,用cmd和sublime,pycharm编译器执行脚本时,并非

销毁对象时执行__del__,而是在实例化对象时执行的;只有在python自带的IDE中才会在销毁对象时执行,我也不知道为什么。


3. 公有和私有属性,方法

python 的类中,如果有一些属性不想给外部权限来访问或者修改,可以在属性或者方法的名字前加俩下划线__,声明为

私有属性。则在外部调用该属性时返回ValueError.

class girl(object)
    def __init__(self,name,phone):
        self.name = name
        self.__phone = phone
Mary = girl("马力",110)

使用场景:如果想只给外部访问的权限,不给修改的权限。可以在类里头定义一个 返回 属性的函数
class girl(object)
    def __init__(self,name,phone):
        self.name = name
        self.__phone = phone
    def want_her_phone(self):
        print(self.__phone)
Mary = girl("马力",110)
Mary.want_her_phone() >> 110

使用场景2:给与外部访问与修改权限,但修改值应按照设计的范围来。

class girl(object):
	def __init__(self,name):
		self.name = name
		self.__phone = 12312312312
	def want_her_phone(self):
		print(self.__phone)
		return self.__phone
	def change_phone(self,new):
		if len(str(new)) != 11 or str(new)[:3] not in ['153','138','157','183']:
			raise ValueError('you cheat me!')
		self.__phone = new

Mary = girl("玛丽")

Mary.change_phone(15734567654) >> 修改phone 属性
另外:实际上私有变量的工作原理是将变量名改为: _类名__变量名,仍可以通过这个来调用。
class girl(object)
    def __init__(self,name,phone):
        self.name = name
        self.__phone = phone
Mary = girl("马力",110)
print(Mary._girl__phone)
在属性名前只加一个下划线 _ 也算私有属性,但仍然能访问和修改,但尽量别改。

4. 注解 @property

从上几个例子可以看出,想要对对象的属性值设定一定的范围,就得用到函数,修改时要 obj.method(),代码很长很不爽,此时

使用装饰器@property可以让你直接跟用属性一样,直接点 . obj.attr = x。

语法是:先定义两个函数,函数名为属性名,第一个函数返回属性值,第二个函数修改属性值。然后在第一个函数头上写个

@property, 在第二个函数头上写个 @属性名.setter就行

 

class girl(object):
	def __init__(self):
		self.__age = 30
	@property	
	def age(self):
		return self.__age
	@age.setter
	def age(self,value):
		if not isinstance(value,int):
			raise ValueError('must be int!')
		if value > 28 or value < 18:
			raise ValueError("Is it not pretty enough for you?")
		self._age = value

a = girl()
a.age = 35 # 不符合范围,报错
print(a.age) 
5. 类的打印信息

如果类直接打印 print(girl()) 会出现一个内存地址,不仅没用而且让人看起来很迷惑。我们可以使用 __str__函数来修改

类的打印信息,打印出我们想让它显示的内容。

class girl(object):
    def __str__(self):
        return "这是一个类"
print(girl()) >>这是一个类
6. 引用统计

先引入sys模块,import sys。然后sys.getrefcount(obj),返回被引用的次数。


import sys

print(sys.getrefcount(int))>>69次sys模块里
7. 类方法,静态方法

@staticmethod

通常情况下,在类中定义的所有函数都是对象的绑定方法,对象在调用绑定方法时会自动将自己作为

参数传递给方法的第一个参数。但是静态方法就不会把自己传进去,相当于一个全局函数样的:

class A(object):

    @staticmethod
    def fn1():
        print("haha")
A.fn1() >> haha
a = A()
a.fn1() >> haha
@classmethod

与实例方法相似,只不过首个参数会自动接收类对象,类对象可以调用。但实际上,实例对象也能用,

会把自己的父类传入第一个参数。

class A(object):
    @classmethod
    def fn2(cls,a,b): # cls跟self一样,只是为了语义化,可以用任意的字符
        print(cls,a,b)
A.fn2(1,2) >><class '__main__.A'> 1 2
a = A()
a.fn2(3,4) >><class '__main__.A'> 3 4
另外,类中定义的实例方法,即正常定义的方法,类对象也能调用,只不过会当成一个普通函数,第一个参数并不会自动

接收实例对象,包括self,定义了几个参数,就要给几个参数。

class A(object):
    def fn3(self,a,b):
        print(self,a,b)
A.fn3(1,2,3) >> 1,2,3
a = A()
a.fn3(123,12) >> 
<__main__.A object at 0x007306F0> 123 12
4 三个特性

 面对对象的三个特性为: 封装,继承,多态。

封装: 应该注意到了,类的定义格式很像函数,将一大堆代码写在类的肚子里,如果有多个对象很多特征相似,可以

  把这些特征封装进一个类中。

继承: 类有继承的功能,所谓继承就是从一个类里头实例化一个对象,你没写这个对象的属性方法,这个对象从他的类中

 得到了所有的属性方法,可以直接调用。

class dog(object):
    def __init__(self)
        self.leg = 4
    def attack_method(self):
        print("the dog is bitting!")

gou = dog() # 实例对象gou 从类 dog 中继承了所有的属性和方法
gou.leg >> 4
gou.attack_method()  >> the dog is bitting!

类也能继承,一个类定义的时候,括号中有个object参数,表示从 python 自带的object类中继承相应的属性以及方法。

 同样的,也能从其他类中继承属性和方法

class animal(object):
    def __init__(self):
        self.look = "cute"
class dog(animal):
    def looklike(self):
        print(self.look)  
        # 调用了未定义的 look 属性

gou = dog()
gou.looklike() >> cute
gou.look >> cute  # dog中未定义的属性
 多重继承,有时候一个对象不仅有这个类的特性,还有那个类的特性,此时可以可以定义一个类,继承多个类。

class animal(object):
    def __init__(self,color):
        self.color = color
class dog(object):
    def __init__(self,name):
        self.name = name
    def wang(self):
        print("汪!")
class village_dog(animal, dog):
    pass # 从animal和dog中继承

gou = village_dog("黄色")
gou.color >> "黄色"
gou.wang() >> "汪!"
# 要注意的是,animal和dog中都有 init 函数,init函数只会执行一个,就近选择,如果自身有用自己的,自己没,用参数里靠前的那个类的
 多态:
  多态这个特性是理所当然的,A类继承自B类,B类有继承自C类,C类甚至继承自D和E类。则从A类实例化后的对象,

判断类型时,可以是 A,B,C,D,E 类,针对这些类定义的函数他都能用,这就是多态。

class animal(object):
    def __init__(self,color):
        self.color = color
class dog(object):
    def __init__(self,name):
        self.name = name
    def wang(self):
        print("汪!")
class village_dog(animal, dog):
    pass # 从animal和dog中继承

gou = village_dog("sdfa")
isinstance(gou,dog) >> True
isinstance(gou,animal) >> True
# isinstan 判断是否为XX类型  如果用type 则只显示 village 类
4.实例属性和类属性
实例属性就是__init__绑定的那些属性,类属性是在类里头直接写:attr = value,就设置了一个类属性。
但是实例会继承类的这个属性,实例重写时覆盖。
 5 类的一些操作方法

 dir(obj) 显示类的所有属性和方法
修改/添加属性,方法 : 直接点 . obj.haha = "哈哈" obj.asdf = lambda x: return x+1
hasattr(obj,attr)
getattr(obj,attr,default) default为找不到时默认返回,不写的话,找不到时报错
setattr(obj,attr,value)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值