python_类的学习笔记,空闲的时间翻翻防止遗忘知识点

类、对象及其简单示例

类:具有相同属性和技能的一类事物。将一个类实例化,就得到了对象。

class Person:
    # 静态变量,静态字段
    mind = "华山大弟子"
    animal = "高级动物"
    def __init__(self):
        pass
    # 方法,动态变量
    def func(self):
        print("函数")
# 从类名角度
    # 静态字段
print(Person.__dict__) # 查看类中的全部内容
{'__module__': '__main__', 'mind': '华山大弟子', 'animal': '高级动物', '__init__': <function Person.__init__ at 0x00000273BA54CEA0>, 'func': <function Person.func at 0x00000273BA54CE18>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
print(Person.mind) # 查看
Person.money = "货币" # 增加静态字段
print(Person.money)
华山大弟子
货币
Person.animal = "高级高级高级动物" # 修改静态变量
print(Person.animal)
高级高级高级动物
del Person.mind # 删除
print(Person.__dict__)
{'__module__': '__main__', 'animal': '高级高级高级动物', '__init__': <function Person.__init__ at 0x00000273BA54CEA0>, 'func': <function Person.func at 0x00000273BA54CE18>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'money': '货币'}
# 操作类中的方法,除了类方法,静态方法,需要类名调用之外,剩下的方法都要对象调用
class Person:
    # 静态变量,静态字段
    mind = "华山大弟子"
    animal = "高级动物"
    def __init__(self,name,money):
        self.name = name
        self.money = money
    # 方法,动态变量
    def func(self):
        print("函数")
obj = Person("华山大弟子",1000)  # 产生示例传给obj
print(obj.name)
华山大弟子
# 查询对象空间的全部内容
print(obj.__dict__)
{'name': '华山大弟子', 'money': 1000}
组合

class GameRole:
    def __init__(self,name,sex,age,ad,hp):
        self.name = name
        self.sex = sex
        self.age = age
        self.ad = ad
        self.hp = hp

    def attack(self,p):
        p.hp = p.hp - self.ad
        print('%s赤手空拳打了%s%s滴血,%s还剩%s血' %(self.name,p.name,self.ad,p.name,p.hp))


    def add_moto(self,mo):
        self.mo = mo

    def add_weapon(self,wea):
        self.wea = wea

    def road_rush(self,p1):
        p1.hp = p1.hp - self.ad - self.wea.ad
        print('%s骑着%s打了骑着%s的%s一%s,%s哭了,还剩%s血' \
              %(self.name,self.mo.name,p1.mo.name,p1.name,self.wea.name,p1.name,p1.hp))
class Weapon:
    def __init__(self,name,ad):
        self.name = name
        self.ad = ad

    def fight(self,p1,p2):
        p2.hp = p2.hp - p1.ad - self.ad
        # print(' %s利用%s打了%s一%s,%s还剩%s血' %(p1.name,self.name,p2.name,self.name,p2.name,p2.hp))
        print('{0}利用{1}打了{2}一{1},{2}还剩{3}血'.format(p1.name,self.name,p2.name,p2.hp))


class Moto:
    def __init__(self,name,speed):
        self.name = name
        self.speed = speed

    def drive(self,p1):
        print('%s骑着%s开着%d迈的车行驶在赛道上' % (p1.name,self.name,self.speed))

p1 = GameRole('小姐姐','女',18,20,200)
p2 = GameRole('小哥哥','男',20,30,150)
p3 = GameRole('大姐姐','女',19,50,80)
w1 = Weapon('平底锅',20)
w2 = Weapon('斧子',50)
w3 = Weapon('双节棍',65)
m1 = Moto('小踏板',60)
m2 = Moto('雅马哈',80)
m3 = Moto('宝马',120)
p1.add_moto(m3)
p1.add_weapon(w3)
p2.add_moto(m2)
p1.road_rush(p2)
小姐姐骑着宝马打了骑着雅马哈的小哥哥一双节棍,小哥哥哭了,还剩65血
# 定义一个类,计算圆的面积
class Circle:
    def __init__(self,r):
        self.pi = 3.1415
        self.r = r
    def area(self):
        return self.r**2*self.pi
    def permeter(self):
        return self.r*2*self.pi
c1 = Circle(3)
print(c1.area(),c1.permeter())
28.273500000000002 18.849
# 定义一个圆环,计算圆环的面积和周长
class ring :
    def __init__(self,r1,r2):
        self.pi = 3.1415
        self.r1 = r1
        self.r2 = r2
    def area(self):
        return self.r1**2*self.pi - self.r2**2*self.pi
    def permeter(self):
        return self.r1*2*self.pi - self.r2*2*self.pi
r = ring(6,4)
print(r.area(),r.permeter())
62.830000000000005 12.565999999999999
继承

(1)调用父类构造函数
(2)方法重写,重写父类中的方法

class Parent:        # 定义父类
    def __init__(self):
        print("我是父类构造函数")
    def myMethod(self):
        print("调用父类方法")

class Child(Parent): # 定义子类
    def __init__(self):
        super().__init__()  ## 调用父类的构造方法
        print("我是子类构造方法")
    def myMethod(self):  # 重写父类的方法
        print('调用子类方法')
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
我是父类构造函数
我是子类构造方法
调用子类方法

限制性父类中的myMethod方法再执行子类的myMethod方法

class Parent:        # 定义父类
    def __init__(self):
        print("我是父类构造函数")
    def myMethod(self):
        print("调用父类方法")

class Child(Parent): # 定义子类
    def __init__(self):
        super().__init__()  ## 调用父类的构造方法
        print("我是子类构造方法")
    def myMethod(self):  # 重写父类的方法
        super().myMethod()
        print('调用子类方法')
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
我是父类构造函数
我是子类构造方法
调用父类方法
调用子类方法
类:经典类和新式类

新式类:凡是继承object类都是新式类(Python3版本中所有的类都是新式类,都默认继承了object类。class A = classA(object))
经典类:不继承object类的都是经典类,经典类只存在于Python2版本中。python2默认不继承object类。

继承:单继承和多继承

单继承:新式类,经典类查询顺序一样
多继承:新式类:遵循广度优先;经典类:遵循广度优先

# 多继承的新式类
class A:
    def func(self):
        print("in A")
class B(A):
    def func(self):
        print("in B")
class C(A):
    def func(self):
        print("in C")
class D(B):
    def func(self):
        print("in D")
class E(C):
    def func(self):
        print("in E")
class F(D,E):
    def func(self):
        print("in F")
f1 = F()
f1.func()
in F

class A:
    def func(self):
        print("in A")
class B(A):
    def func(self):
        print("in B")
class C(A):
    def func(self):
        print("in C")
class D(B):
    def func(self):
        print("in D")
class E(C):
    def func(self):
        print("in E")
class F(D,E):
    pass
#     def func(self):
#         print("in F")
f1 = F()
f1.func()
 
in D

class A:
    def func(self):
        print("in A")
class B(A):
    def func(self):
        print("in B")
class C(A):
    def func(self):
        print("in C")
class D(B):
    pass
#     def func(self):
#         print("in D")
class E(C):
    def func(self):
        print("in E")
class F(D,E):
    pass
#     def func(self):
#         print("in F")
f1 = F()
f1.func()
 
in B

class A:
    def func(self):
        print("in A")
class B(A):
    pass
#     def func(self):
#         print("in B")
class C(A):
    def func(self):
        print("in C")
class D(B):
    pass
#     def func(self):
#         print("in D")
class E(C):
    def func(self):
        print("in E")
class F(D,E):
    pass
#     def func(self):
#         print("in F")
f1 = F()
f1.func()
 
in E

class A:
    def func(self):
        print("in A")
class B(A):
    pass
#     def func(self):
#         print("in B")
class C(A):
    def func(self):
        print("in C")
class D(B):
    pass
#     def func(self):
#         print("in D")
class E(C):
    pass
#     def func(self):
#         print("in E")
class F(D,E):
    pass
#     def func(self):
#         print("in F")
f1 = F()
f1.func()
 
in C

class A:
    def func(self):
        print("in A")
class B(A):
    pass
#     def func(self):
#         print("in B")
class C(A):
    pass
#     def func(self):
#         print("in C")
class D(B):
    pass
#     def func(self):
#         print("in D")
class E(C):
    pass
#     def func(self):
#         print("in E")
class F(D,E):
    pass
#     def func(self):
#         print("in F")
f1 = F()
f1.func()
 
in A

上述继承关系如下钻石搜索(层次遍历)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Zo5xLg1-1588040851273)(attachment:image.png)]

小结:

继承使得类与类之间发生关系,而组合则使得对象与对象之间发生关系。
子类中即实现父类的方法,又实现自己的方法:
super().父类方法名(参数(自传self))
父类名.父类方法名(参数)
经典类不继承object,新式类默认继承object。
经典类深度优先继承,新式类广度优先遍历。

抽象类、接口类

接口类和抽象类在java中是两个不同的东西。但在Python中其实是一样的。
Python没有多态但是有多继承,java没有多继承但是有多态。
Python中没有接口这个概念。

from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta): # 抽象类接口,定义开发规范
    @abstractmethod    # 装饰器,继承的类必须有pay方法!!!
    def pay(self):
        pass
class Alipay(Payment):
    def __init__(self,money):
        self.money = money
    def pay1(self):
        print("使用支付宝支付%s"%(self.money))
a1 = Alipay(100)
a1.pay1()
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-4-c35b7c62a951> in <module>()
      9     def pay1(self):
     10         print("使用支付宝支付%s"%(self.money))
---> 11 a1 = Alipay(100)
     12 a1.pay1()


TypeError: Can't instantiate abstract class Alipay with abstract methods pay
from abc import ABCMeta,abstractmethod
# 强制制定一个规范,凡是继承我的类中必须有pay()方法,如果没有,实例化的时候回报错。
class Payment(metaclass=ABCMeta): # 抽象类接口,定义开发规范
    @abstractmethod    # 装饰器,继承的类必须有pay方法
    def pay(self):
        pass
class Alipay(Payment):
    def __init__(self,money):
        self.money = money
    def pay(self):
        print("使用支付宝支付%s"%(self.money))
a1 = Alipay(100)
a1.pay()
使用支付宝支付100
多态

Python面向对象的三大特征之一:
多态:Python处处是多态.
Python是弱类型语言 name = 666
java是强类型语言 int i = 5;

# Python不管什么类型,传入函数,封装到对象中都可以。
def func(a):
    print(a)
func([1,2,3,4,56])
func(111)
[1, 2, 3, 4, 56]
111
封装

实例化一个对象,给帝乡空间封装一些属性,这就是广义上的封装。
那么什么是狭义的封装呢?
将对象进行私有制,如一些私有的成员:私有静态字段、私有方法、私有对象属性。

class A:
    name = "华山大弟子"
    def func(self):
        print("func函数")
a1 = A()
a1.name
'华山大弟子'
class A:
    __name = "华山大弟子"
    def func(self):
        print("func函数")
a1 = A()
a1.__name #实例化对象不能访问私有静态字段
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-9-110f405a238b> in <module>()
      4         print("func函数")
      5 a1 = A()
----> 6 a1.__name


AttributeError: 'A' object has no attribute '__name'
class A:
    __name = "华山大弟子"
    def func(self):
        print("func函数")
a1 = A()
A.__name #类本身不能访问私有静态字段
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-10-a432ca275fea> in <module>()
      4         print("func函数")
      5 a1 = A()
----> 6 A.__name #实例化对象不能访问私有静态字段


AttributeError: type object 'A' has no attribute '__name'
class A:
    __name = "华山大弟子"
    def func(self):
        print(self.__name) # 对于私有静态变量,类的内部可以访问
        print(A.__name)
        print("func函数")
a1 = A()
a1.func()  
华山大弟子
华山大弟子
func函数
class B:
    __money = 10000000
class C(B):
    name = "华山大弟子"
    __age = 20
    def func(self):
        print(self.__money)
        print("func......")
c1 = C
c1.func()
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-14-53ef440fd8fd> in <module>()
      8         print("func......")
      9 c1 = C
---> 10 c1.func()


TypeError: func() missing 1 required positional argument: 'self'
小结

对于私有静态字段来说,只能在本类内部访问,类的外部、派生类均不可访问。
对于私有方法来说,

# 有方法可以访问,但是工作中千万不能使用
class B:
    __money = 10000000
class C(B):
    name = "华山大弟子"
    __age = 20
    def func(self):
        print(self._B__money)  # 其实在Python在内存中将私有静态变量名字加上了“_”“类名”和变量名。工作中千万不要这么用!!!
        print("func......")
c1 = C()
c1.func()
10000000
func......
class B:
    __money = 10000000
class C(B):
    name = "华山大弟子"
    def __func(self):
        print("---")
c = C()
c.__func()
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-24-a0f9a8859926> in <module>()
      6         print("---")
      7 c = C()
----> 8 print(c.__func())


AttributeError: 'C' object has no attribute '__func'
class B:
    __money = 10000000
class C(B):
    name = "华山大弟子"
    def __func(self):
        print("---")
c = C()
c._C__func()   # 利用漏洞可以访问,工作中千万不要这么搞,会被当做野生程序员的......
---
None
class B:
    __money = 10000000
    def __func1(self):
        print("in B")
class C(B):
    name = "华山大弟子"
    def func(self):
        print("---")
        self.__func1()
c = C()
c.func() # 类的派生类也不能访问,私有方法,只有在类自己本身。。。。因为在私有方法前面加了前缀
---



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-28-d7b8780584b0> in <module>()
      9         self.__func1()
     10 c = C()
---> 11 c.func()


<ipython-input-28-d7b8780584b0> in func(self)
      7     def func(self):
      8         print("---")
----> 9         self.__func1()
     10 c = C()
     11 c.func()


AttributeError: 'C' object has no attribute '_C__func1'
属性property
class Person:
    def __init__(self,name,hight,weight):
        self.name = name
        self.__hight = hight
        self.__weight = weight
    
    def bmi(self):
        return "%s的bmi值是%s"%(self.name,self.__weight/self.__hight**2)
p1 = Person("华山大弟子",1.78,72)
p1.bmi()
'华山大弟子的bmi值是22.724403484408533'
# 添加一个装饰器,将函数转变为属性
# property修改了函数的调用方式。将一个方法伪装成一个属性,在代码级别并没有啥本质区别,
# 只是看起来更加合理。
class Person:
    def __init__(self,name,hight,weight):
        self.name = name
        self.__hight = hight
        self.__weight = weight
    @property
    def bmi(self):
        return "%s的bmi值是%s"%(self.name,self.__weight/self.__hight**2)
p1 = Person("华山大弟子",1.78,72)
p1.bmi  # 已经伪装成属性了
'华山大弟子的bmi值是22.724403484408533'
# 触发模式
class A:
    def __init__(self,name,age):
        self.name = name
        self.__age = age
    @property
    def age(self):
        return self.__age
    @age.setter  # setter触发器是属性中带的方法
    def age(self,age1):
        print(age1)
        print("in age(self,age1)")
a1 = A("华山大弟子",20)
print(a1.age)
a1.age = 10000
20
10000
in age(self,age1)

类方法和静态方法

类方法:通过类名调用的方法,类方法中第一个参数约定俗成为cls,python自动将类空间传给cls。当方法不需要对象参与的时候可以使用。
对类中的静态变量需要进行改变,需要使用类方法。继承中,父类得到子类的类空间。

# 类方法
class A:
    def func(self):
        print(self)
    @classmethod # 类方法
    def func1(cls):
        print(cls)
a1 = A()
a1.func()
A.func1()
a1.func1() # 对象和类都可以调用,得到的都是类本身
<__main__.A object at 0x000001B2D22ADDA0>
<class '__main__.A'>
<class '__main__.A'>
# 当方法不需要对象参与的时候可以使用
class A:
    name = "华山大弟子"
    count = 1
    @classmethod
    def func(cls):  # 此方法无需对象参与
        return cls.name+str(cls.count)
A.func()
'华山大弟子1'
# 继承中,父类得到子类的类空间
class A:
    name = "华山大弟子"
    count = 1
    @classmethod
    def func(cls):  # 此方法无需对象参与
        return cls.name+str(cls.count)
class B(A):
    pass
B.func()
'华山大弟子1'
class A:
    age = 18
    @classmethod
    def func(cls):  # 此方法无需对象参与
        return cls.age
class B(A):
    age=17
B.func()
17
静态方法

好处:1、使代码看起来结构清晰;

class A:
    @staticmethod
    def func():
        print("我是静态方法")
A.func()
a = A()
a.func()
我是静态方法
我是静态方法

内置函数

# isinstance()  用该方法去判断的时候,子类的对象即是子类对象也是父类对象
#    如果用type()判断的是子类。如果不想判断继承关系就用type(obj) is 类名。
class A:
    pass
class B(A):
    pass
b = B()
print(isinstance(b,A)) 
print(isinstance(b,B))
True
True
# == 判断值相等,值运算;is内存地址相等,身份相等。is要求更苛刻,不仅要求值相等,还要求内存地址相同。
a = 1111
b = 1111
print(id(a))
print(id(b))
print(a==b)
print(a is b)
1341327237744
1341327237776
True
False
# issubclass()  判断类与类之间的继承关系
class Animal:
    pass
class Cat(Animal):
    pass
class Person(Animal):
    pass
issubclass(Cat,Animal)  # 判断Cat是不是Animal的子类
True
两个内置函数 *
反射 ******

方法:getattr、hasattr、setattr、delattr
用字符串数据类型的变量名来访问这个变量的值

内置方法 ***
# 反射的使用
# 使用类放射

## 原始的方法
# class Student:
#     def __init__(self):pass
#     def look_course(self):
#         print("查看课程")
#     def choose_course(self):
#         print("选择课程")
#     def choosed_course(self):
#         print("查看已选课程")
# student = Student()
# num = "look_course"
# if num == "look_course":
#     student.look_course()

# 反射
class Student:
    ROLE = "Student"
    score = 100
    @classmethod
    def check_score(cls):
        print(cls.ROLE)
        print(cls.score)
        print("检查分数!!!")
    @staticmethod
    def login():
        print("登陆")
user_input = "ROLE"
# eval 这个东西 明确的写在你的代码里才可以用
# 反射查看属性
getattr(Student,user_input) # 用字符串的变量名来拿到变量值
# 发射调用方法
getattr(Student,"check_score")()
# 反射调用静态方法
getattr(Student,"login")()

# hasattr 判断是否存在该方法
print(hasattr(Student,"huashan"))
print(hasattr(Student,"login"))
Student
100
检查分数!!!
登陆
False
True
x = 7
eval("3**x")  # 不安全
2187
# 使用对象反射
class A:
    def __init__(self,age):
        self.age = age
    def func(self):
        print("func 函数")
a = A(10)
print(getattr(a,"age"))
getattr(a,"func")()
10
func 函数
# 反射自己模块中的内容
# import相当于导入了一个模块,模块哪个导入哪个没导入,在python的
#  解释器汇总记录

import os
print(getattr(os,"rename"))
<built-in function rename>
反射

hasattr、getattr
类名.名字 getattr(类名,名字)
对象名.名字 getattr(对象名,名字)
模块名.名字 getattr(模块,名字)
自己文件.名字
import sys
getattr(sys.modules(“main”),‘名字’)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值