小尹学python

导航

Python:面向对象

class JackPerson:  # 首字母大写,命名驼峰原则
    # 实例变量
    def __init__(self, k):  # 初始化方法,自动执行方法
        self.data = k

    # 绑定方法
    def xxx(self, x, y):  # 定义一个方法
        data = x + y
        print(data, self.data)

    def yyy(self, i, j):
        data = i * j
        print(data, self.data)


# 1、根据类创建一个对象,内存的一块区域
# 2、执行__init__方法,模块会将创建的那块区域地址当self参数传进去
# 3、内部方法可以相互调用
a = JackPerson('你好')  # 实例化一个对象i,创建一块区域,初始化一些数据
a.xxx(1, 2)  # 3 你好   也可以用JackPerson.xxx(a,1,2)
a.yyy(2, 3)  # 6 你好

b = JackPerson('哈哈')
b.xxx('人','狗')  # 人狗 哈哈
b.yyy('猫',2)  # 猫猫 哈哈


class UserInfor:
    def __init__(self,name,psw):
        self.name = name
        self.psw = psw

def run():
    userinfor = []
    while True:
        user = input('请输入用户名:')
        if user.upper() == 'Q':
            break
        psw = input('请输入密码:')
        user_objct = UserInfor(user,psw)
        userinfor.append(user_objct)  # 将每次输入的用户名和密码实例化,并将这一实例化对象放进列表里,列表里是一块块的内存
        print(userinfor)  # 类似于[<__main__.UserInfor object at 0x000001C40A645D60>, <__main__.UserInfor object at 0x000001C40A645D00>]
    for i in userinfor:
        print(i.name,i.psw)

run()


# 面向对象三大特性:封装、继承、多态
# 封装:将同一类方法封装到一个类中、将数据封装到对象中,将一些数据通过__init__初始化方法封装到对象中,以供日后使用
# 继承

# 示例一
class Father:  # 父类
    def func(self,a):
        print(a)

class Son(Father):  # 子类,继承父类中的方法
    def show(self,b):
        print(b)

s1 = Son()
s1.func(3)  # 优先在自己类中找,找不到再到父类中找
s1.show(4)

# 示例二
class Base:
    def f1(self):
        print('Base.f1')

class Foo(Base):
    def f2(self):
        print('befor')
        self.f1()  # 调用f1方法,相当于obj.f1
        print('foo.f2')

obj = Foo()
obj.f2()  # 输出: befor   Base.f1   foo.f2


# 示例三
class Base:
    def f1(self):
        print('Base.f1')

class Foo(Base):
    def f2(self):
        print('befor')
        self.f1()  # 调用f1方法,相当于obj.f1,f1在自己这里能找到,所以调用自身区域的f1
        print('foo.f2')
    def f1(self):
        print('foo.f1')

obj = Foo()
obj.f2()  # 输出:   befor    foo.f1     foo.f2


# 示例三
class Base:
    def f1(self):
        print('befor')
        self.f2()  # 调用f2方法,相当于obj.f2,因此调用的是Foo类里的f2
        print('base.f2')
    def f2(self):
        print('Base.f1')

class Foo(Base):
    def f2(self):
        print('foo.f1')

obj = Foo()
obj.f1()  # 输出: befor  foo.f1  base.f2

# 示例三:多继承
class A1:
    def f1(self):
        print('A1.f1')
    def f2(self):
        print('A2.f2')

class B1:
    def f1(self):
        print('B1.f1')
    def f3(self):
        print('B1.f3')

class C1(A1,B1):
    def f4(self):
        print('C1.f4')

xxx = C1()
xxx.f1()  # A1.f1  多继承情况下,优先继承左边的函数

# 示例四:多层次继承关系
class Base:
    def f1(self):
        print('Base.f1')
    def f2(self):
        print('Base.f2')

class Son1:
    def f1(self):
        print('Son1.f1')
    def f2(self):
        print('Son1.f2')

class Son2(Base):
    def f1(self):
        print('Son2.f1')
    def f4(self):
        print('Son2.f4')

class Children(Son2,Son1):
    def f1(self):
        print('Children.f1')
    def f5(self):
        print('Children.f5')

family = Children()
family.f2()  # Base.f2


#  多态
class  Email(object):
    def send(self):
        print('发邮件')

class  Wechat(object):
    def send(self):
        print('发微信')

def func(arg):
    v = arg.send()

v1 = Email()
func(v1)  # 发邮件
v2 = Wechat()
func(v2)  # 发微信

# 对象成员:变量(实例变量、类变量)、方法(绑定方法、类方法、静态方法)

class Person(object):
    contry = '中国'  # 类变量
    def __init__(self,age,name):
        self.age = age
        self.name = name

    def show(self):
        message = '{}是{}人,今年{}岁'.format(self.name,Person.contry,self.age)  # Person.contry也可以表示为self.contry
        print(message)

p1 = Person(18,'Jack')  # 实例变量
p1.show()  # Jack是中国人,今年18岁
print(p1.age)
print(p1.name)
print(p1.contry)

p1.name = 'Lilei'  # 将name重置为Lilei
p1.area = '浙江省'  # 新增一个实例变量
p1.contry = 'Datang'  # p1中新增一个实例变量
print(p1.contry)  # Datang
print(Person.contry)  # 中国
Person.contry = '美国'  # 将类变量改成美国
print(Person.contry)  # 美国


# 如果有继承关系,在自己找不到变量,则到父类中找
class Base(object):
    contry = '元朝'

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

    def show(self):
        message = '{}是{}人,今年{}岁'.format(self.name,Person.contry,self.age)  # Person.contry也可以表示为self.contry
        print(message)

p2 = Person(22,'Jim')
Person.contry = '明朝'  # 在Person类中新增contry = '明朝'
Base.contry = '秦朝'  # 将Base类的contry改成秦朝
p2.contry = '汉朝' #  在p2中新增contry = '汉朝'


# 方法:绑定方法、类方法、静态方法,取决于你用到哪些参数
class Foo(object):
    def __init__(self,name):
        self.name = name
    def f1(self):
        print('绑定方法',self.name)

    @classmethod  # 类方法固定搭配
    def f2(cls):  # 默认有一个cls参数
        print('类方法',cls)

    @staticmethod  # 静态方法固定搭配
    def f3():  # 参数可以没有或者很多个
        print('静态方法')

# 绑定方法调用
obj = Foo('张学友')
obj.f1()

# 类方法调用,cls就是这个方法的类
Foo.f2()
obj.f2()

# 静态方法调用
Foo.f3()
obj.f3()


# 属性:由绑定方法+装饰器组合,属性名和变量名不能重名,否则报错
class Aaa(object):
    def __init__(self,name):
        self.name = name

    def f1(self):
        return 123

    @property
    def f2(self):
        return 333

obj = Aaa('xueyou')
v1 = obj.f1()
v2 = obj.f2 # 可以不用加括号


# 成员修饰符:公有、私有(用双下划线表示)
class Bbb(object):
    def __init__(self,name,age):
        self.__name = name  # 私有变量
        self.age = age  # 公有变量

    def f1(self):
        return self.__name  # 内部可以调用

    def f2(self):
        return self.age

obj = Bbb('学友',28)
#  print(obj.__name) 会报错,无法调用
print(obj.age)


class Ccc(object):
    def fff(self):
        print('公有类方法')

    def __fff(self):
        print('私有类方法')

    def ggg(self):
        print('公有类方法')
        self.__fff()  # 内部可以调用

obj = Ccc()
obj.fff() # 可用
# obj.__fff()  # 不可用
obj.ggg() # 间接调用私有类方法
obj._Ccc__fff()  # 通过这种方式可以引用,不推荐用

# 父类的私有方法,子类无法继承


# 对象嵌套
# 案例
class Stars(object):
    def __init__(self,name,trad):
        self.name = name
        self.trad = trad
    def message(self):
        data = '我叫{},是一个{},请大家多多关注'.format(self.name,self.trad)
        return data

s1 = Stars('张学友','歌手')
s2 = Stars('李连杰','功夫演员')
s3 = Stars('巴特尔','篮球运动员')

class Guilei(object):
    def __init__(self,nationality):
        self.nationality = nationality
        self.stars_list = []

    def add_star(self,star):
        self.stars_list.append(star)

    def add_stars(self,stars):
        for i in stars:
            self.stars_list.append(i)

    def show(self):
        for item in self.stars_list:
            print('我叫{},是一个{},我是{}人'.format(item.name,item.trad,self.nationality))

g1 = Guilei('中国')
g1.add_star(s1)
g1.add_stars([s2,s3])
for item in g1.stars_list:
    print(item.message())
    print(item.name,item.trad)
g1.show()

# >>>
# 我叫张学友,是一个歌手,请大家多多关注
# 张学友 歌手
# 我叫李连杰,是一个功夫演员,请大家多多关注
# 李连杰 功夫演员
# 我叫巴特尔,是一个篮球运动员,请大家多多关注
# 巴特尔 篮球运动员
# 我叫张学友,是一个歌手,我是中国人
# 我叫李连杰,是一个功夫演员,我是中国人
# 我叫巴特尔,是一个篮球运动员,我是中国人

# 特殊成员
# __init__、__new__
class Ddd(object):
    def __init__(self,name):
        print('第二步,初始化对象,在空对象中创建数据')
        self.name = name
    def __new__(cls, *args, **kwargs):  # 用处不大
        print('第一步,创建空对象,并返回')
        return object.__new__(cls)

obj = Ddd('张学友')

# __call__:
class Eee(object):
    def __call__(self, *args, **kwargs):
        print('执行call方法')

obj = Eee()
obj()  # 可以对象加括号执行call方法

#__str__ :展示用
class Fff(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        return '{},{}'.format(self.name,self.age)  # 必须return一个字符串

s1 = Fff("张学友","28")
print(s1) #张学友,28   如果没有__str__,则输出的是一个内存地址

#__dict__:转换成字典
class Ggg(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
s1 = Ggg("张学友","28")
print(s1.__dict__)  # {'name': '张学友', 'age': '28'}


# __getitem__、__setitem__、__detitem__
class Hhh(object):
    def __getitem__(self, item):
        print(item)
    def __setitem__(self, key, value):
        print(key,value)
    def __delitem__(self, key):
        print(key)

obj = Hhh()
obj['xxx']  # xxx
obj['xxx'] = 123  # xxx 123
del obj['xxx']  # xxx


# __enter__、__exit__
class Iii(object):
    def __enter__(self):
        print('进来了')
        return 'fff'
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('出去了')

obj = Iii()
with obj as f:  # f就是enter方法的返回值,也即fff
    print('你好')  # 进来了  你好  出去了


# __add__:相加,另外还有相乘相除等等,
class Jjj(object):
    def __init__(self,name):
        self.name = name
    def __add__(self, other):
        return '{}是{}的字'.format(self.name,other.name)
v1 = Jjj('子美')
v2 = Jjj('杜甫')
v3 = v1 + v2
# 对象+值,内部会执行对象__add__方法,并将加号后面的值当参数传递进去,也即self是v1,other是v2,v3是add的返回值
print(v3)
# 问题:只接受两个相加吗?

posted on 2021-11-13 23:06  小尹学python  阅读(61)  评论(0)    收藏  举报