Python学习9--类和对象

一、基本概念

1、对象: 对象也叫做实例。万物皆对象,对象是具有行为和属性的。
属性: 名词 行为: 动词

2、类:将需求的对象划分为不同的类,具有相同属性和行为的对象被划分到一个类。

3、类和对象之间的关系:
类:模板,蓝图
对象:实体,是具体的实例 ,类是对象的的抽象,对象是类的具体实现
开发的过程中,从分析对象开始,将对象分类,分类时考虑类中的属性和行为

二、类的定义和初始化

1、类的定义:

格式:
class 类名[(父类)]:
类体

对象名=类() :括号中是否有参数,取决于init方法

如下:

class Person:
    '人的类'
    pass
p1=Person()
print(p1,type(p1))
print(p1.__doc__)

输出:

<__main__.Person object at 0x0000022DAE749CF8> <class '__main__.Person'>
人的类

2、类的属性和行为:

属性是以变量绑定的形式来定义的
行为是以函数定义的方式来定义的

1 )定义动态属性和行为
a) 定义动态属性
格式:对象.属性名=属性值

p1 = Person()
p1.name="张三"
p1.age=20
print(p1.name,p1.age)

输出:

张三 20

a) 定义动态行为

class Person:
    '人的类'
    pass

def run(self):
    print("正在跑步")
p1 = Person()
p1.run = run
p1.run(p1)
输出:

```python
正在跑步

2 )定义类中的属性和方法(给实例定义属性和实例定义方法)

a)定义实例方法

class Person:
    '人的类'
    def run(self):
        print("正在跑步")
p1 = Person()
p1.run()
p2 = Person()
p2.run()

输出:

正在跑步
正在跑步

b)定义实例属性:在实例化init方法中初始化属性
放在init中进行实例化的属性,一定是强依赖的属性
注意的是:__init__方法是在创建的时候执行的方法,但不是创建的方法

class Person:
    '人的类'
    def __init__(self,name):
        print("执行init方法")
        self.name=name
        self.age=None
    def run(self):
        print("正在跑步")
p1=Person("张三")
p1.age=20
p1.run()
print(p1.name,p1.age)

p2=Person("李四")
p2.age=30
p2.run()
print(p2.name,p2.age)

输出:

执行init方法
正在跑步
张三 20
执行init方法
正在跑步
李四 30

c) 在实例行为中调用实例属性

class Person:
    '人的类'
    def __init__(self,name):
        print("执行init方法")
        self.name=name
        self.age=None
    def run(self,place="操场"):
        print("{}{}正在{}跑步".format(self.name,self.age,place))
p1=Person("张三")
p1.age=20
p1.run()
print(p1.name,p1.age)

p2=Person("李四")
p2.age=30
p2.run("公园")
print(p2.name,p2.age)

输出:

执行init方法
张三20正在操场跑步
张三 20
执行init方法
李四30正在公园跑步
李四 30

3. 类的成员

类成员主要包括:实例属性 ,实例方法,类属性,类方法,静态方法

1)类属性

实例属性:跟类无关,跟每一个实例相关,每个实例独有
类属性:跟实例无关,跟类相关的属性,所有实例共享

class Person:
    # 类属性
    desc="人的描述"
    def __init__(self,name):
        # 实例属性
        self.name=name
        self.gender=None

    def run(self):
        pass

访问方式:
实例属性的访问:可通过实例.属性方式访问
类属性的访问:类.属性(推荐)和实例.属性的方式访问
如下所示:

class Person:
    # 类属性
    desc="人的描述"
    def __init__(self,name):
        # 实例属性
        self.name=name
        self.gender=None

    def run(self):
        pass
p1 =Person("张三")
print(p1.name)
print(p1.desc)
print(Person.desc)

输出:

张三
人的描述
人的描述

修改方式:
实例属性的修改:实例.属性=修改
类属性的修改: 类.属性=修改(推荐) 实例.属性=不能修改(会在实例下新创建一个属性)

class Person:
    # 类属性
    desc="人的描述"
    def __init__(self,name):
        # 实例属性
        self.name=name
        self.gender=None

    def run(self):
        pass
p1 =Person("张三")
print(p1.name)
p1.name = "张三_new"
print(p1.name)
print("=================")
Person.desc = "描述_new"
print("p1.desc:{}".format(p1.desc))
print("Person.desc:{}".format(Person.desc))

print("==================")
p2 = Person("李四")
p2.desc = "new_new"
print("Person.desc:{}".format(Person.desc))
print("p1.desc:{}".format(p1.desc))
print("p2.desc:{}".format(p2.desc))

输出:

张三
张三_new
=================
p1.desc:描述_new
Person.desc:描述_new
==================
Person.desc:描述_new
p1.desc:描述_new
p2.desc:new_new

类属性的应用:定义所有对象都公用的属性。

2)类方法
实例方法:跟实例相关,跟类没有关系,实例独享
类方法:跟具体实例无关,跟类有关,实例共享
a)相关定义方法如下:

class  Person:
    #类方法,cls指当前类
    @classmethod
    def fun1(cls):
        print("类方法执行")
    #实例方法
    def run(self):
        print("跑步")
    def __init__(self,name):
        self.name =name
        self.age = None
    #类方法,完成实例的复制
    @classmethod
    def copy(cls,oldperson):
        return cls(oldperson.name)

p1 =  Person("张三")
p2 = Person.copy(p1)
print(p2.name)

输出:

张三

b)类方法和实例方法的访问
类方法的访问: (1)类.方法(推荐) ; (2) 实例.方法
实例方法访问 : (1) 类.方法(不推荐); (2) 实例.方法

class  Person:
    #类方法,cls指当前类
    @classmethod
    def fun1(cls):
        print("类方法执行")
    #实例方法
    def run(self):
        print("跑步")
    def __init__(self,name):
        self.name =name
        self.age = None
    #类方法,完成实例的复制
    @classmethod
    def copy(cls,oldperson):
        return cls(oldperson.name)

p1 =  Person("张三")
p1.age = 18
p1.run()
Person.fun1()
p1.run()

输出:

跑步
类方法执行
跑步

c)类方法的使用场合
创建对象、复制对象

class  Person:
    def __init__(self,name):
        self.name =name
        self.age = None
    #类方法,完成实例的复制
    @classmethod
    def copy(cls,oldperson):
        return cls(oldperson.name)

p1 =  Person("张三")

p2 =Person.copy(p1)
print(p1.name,p2.name)
print(id(p1),id(p2))

输出:

张三 张三
2272481559048 2272481562296

d)类属性、实例属性在类方法和实例方法中的调用
方法都是为了属性的改变服务
(1)类方法中访问类属性,推荐使用cls.属性(cls相当于类名)

class Person:
    desc="人的描述"
    # 类方法,cls:指当前类
    @classmethod
    def cm(cls):
        print("类方法执行")
        print("类方法访问类属性",Person.desc)
        print("类方法访问类属性",cls.desc)
Person.cm()

输出:

类方法执行
类方法访问类属性 人的描述
类方法访问类属性 人的描述

(2)实例方法中访问类属性
建议使用self.__class__.属性格式

class Person:
    desc="人的描述"

    def fun1(self):
        print("实例方法执行")
        print("实例方法访问类属性",Person.desc)
        #self.__class__相当于cls,只当前类
        print("实例方法访问类属性",self.__class__.desc)
p1 = Person()
p1.fun1()

输出:

实例方法执行
实例方法访问类属性 人的描述
实例方法访问类属性 人的描述

(3)类方法中访问实例属性
不合理,因为类方法是为类而服务的
不建议使用,如果要使用,可参照如下方法

class Person:
    def __init__(self, name):
        self.name = name
        self.birthday = None

    # 类方法,cls:指当前类
    @classmethod
    def cm(cls,p):
        print("类方法执行")
        print("类方法中访问实例属性", p.name)
p1=Person("张三")
Person.cm(p1)

输出:

类方法执行
类方法中访问实例属性 张三

(4)实例方法访问实例属性(最重要,最常见)

class Person:
    def __init__(self, name):
        self.name = name
        self.birthday = None

    def run(self):
        print("实例方法访问实例属性",self.name)
p1=Person("张三")
p1.run()

输出:

实例方法访问实例属性 张三

3)静态方法
静态方法跟类不相关,跟对象更不相关
定义的时候需要使用@staticmethod装饰
如下:

class Person:
    def __init__(self, name):
        self.name = name

    @staticmethod
    def sta():
        print("静态方法执行")

    @staticmethod
    def makefriend(p1,p2):
        print("{}和{}交朋友".format(p1.name,p2.name))
def makefriend(p1,p2):
    print("{}和{}交朋友".format(p1.name,p2.name))
# 静态方法的访问。通过类名访问
Person.sta()
p1=Person("张三")
p2=Person("李四")
Person.makefriend(p1,p2)
makefriend(p1,p2)

关于类和实例的选择:
类属性和实例属性:
需要分析 属性是所有对象共享的还是单个对象独享的。
如果是共享的则使用类属性
如果是独享的则使用实例属性

类方法、实例方法、静态方法:
需要分析方法是为了 那个属性服务的
如果定义的方法是为了实例属性操作则使用实例方法
如果定义的方法是为了类属性操作则使用类方法
如果跟谁都没关系则使用静态方法

4. 魔法方法

魔法方法的名字格式为: __xx__
魔法方法执行的时候不需要主动调用,当符合一定条件的时候会自动调用。
a)__new__ 静态方法:在创建对象的时候执行,是真正创建对象的方法
需要注意的是:在方法中必须有return,如果没有没有return则不会执行init初始化方法,也不能成功创建对象

class Person:
    # 不使用staticmethod修饰的特殊静态方法
    def __new__(cls, *args, **kwargs):
        print("new方法执行")
        return super().__new__(cls)
p1 =Person()
print(p1)

输出:

new方法执行
<__main__.Person object at 0x000001AC7F21A978>

当方法中没有return时不会创建,如下:

class Person:
    # 不使用staticmethod修饰的特殊静态方法
    def __new__(cls, *args, **kwargs):
        print("new方法执行")
        #return super().__new__(cls)
p1 =Person()
print(p1)

输出:

new方法执行
None

b)__init__方法:在__new__方法执行完毕之后,对对象进行初始化的方法

class Person:
    def __new__(cls, *args, **kwargs):
        print("new方法执行")
        return super().__new__(cls)
    def __init__(self):
        print("init方法执行")
        self.name = None
p1 =Person()
print(p1)

输出:

new方法执行
init方法执行
<__main__.Person object at 0x0000019E9413C208>

c)__del__方法:当对象销毁的时候会自动调用方法

class Person:
    #不使用staticmethod修饰的特殊静态方法
    def __new__(cls, *args, **kwargs):
        print("new方法执行")
        return super().__new__(cls)

    def __init__(self):
        print("init执行")
        self.name=None

    def __del__(self):
        print("执行del方法")

p=Person()
print(p)
p2=p
del p
print("已执行del语句")
print(p2)
print(p)

输出如下:

    print(p)
NameError: name 'p' is not defined
new方法执行
init执行
<__main__.Person object at 0x0000020205BCCEB8>
已执行del语句
<__main__.Person object at 0x0000020205BCCEB8>
执行del方法

d) __str__方法:当调用内建函数str() format print 会自动调用的方法,返回值是str

class Person:
    def __init__(self,name,age):
        print("init执行")
        self.name=name
        self.age=age
    def __str__(self):
        print("执行str方法")
        # return "person类型的对象"
        return "[name={},age={}]".format(self.name,self.age)
p1=Person("张三","20")
print(p1.__str__())
print(p1)

输出如下:

init执行
执行str方法
[name=张三,age=20]
执行str方法
[name=张三,age=20]

e)__repr__方法:效果和__str__方法一致,如果方法中没有定义__str__,却需要调用__str__,默认调用__repr__

class Person:
    def __init__(self,name,age):
        print("init执行")
        self.name=name
        self.age=age
    def __repr__(self):
        print("执行str方法")
        # return "person类型的对象"
        return "[name={},age={}]".format(self.name,self.age)
p=Person("张三",20)
print(p)

输出:

init执行
执行str方法
[name=张三,age=20]

f) __bytes__方法,使用bytes()时自动调用的方法

class Person:
    def __bytes__(self):
        return b"bytes person class "
p=Person()
print(bytes(p))
print(p.__bytes__())

输出:

b'bytes person class '
b'bytes person class '

5. 动态属性操作

class Person:
    pass
p=Person()
p.name="张三"
p.age=20

a) hasattr(obj,name)判断obj中是否存在(name)指定的属性名

class Person:
    pass
p=Person()
p.name="张三"
p.age=20

print(hasattr(p,"age"))
print(hasattr(p,"age1"))

输出:

True
False

b)setattr(obj,name,value)将obj对象中name属性设置为value

class Person:
    pass
p=Person()
p.name="张三"
p.age=20

setattr(p,"gender","女")
print(p.gender)

输出:

c)getattr(obj,name)将obj对象中的name属性值取出

class Person:

    pass
p=Person()
p.name="张三"
p.age=20
setattr(p,"gender","女")

print(getattr(p,"gender"))

输出:

还可以结合setattr方法一起使用,如下:

an=input("请输入属性名")
setattr(p,an,"北京")
print(getattr(p,an))

d)delatrr(obj,name)删除obj中的name属性

class Person:

    pass
p=Person()
p.name="张三"
p.age=20
setattr(p,"gender","女")

print(getattr(p,"gender"))

delattr(p,"gender")
print(p.gender)

输出:

   print(p.gender)
AttributeError: 'Person' object has no attribute 'gender'
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值