类的方法(八)

方法没有重载 

方法的动态性

Python是动态语言,我们可以动态的为类添加新的方法,或者动态的修改类的已有的方法。

class Person:
    def work(self):
        print("work")

def work2(self):
    print("work2")

Person.work2 = work2   # 方法连接

p = Person()
p.work()
p.work2()

私有属性和私有方法

Python 对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。

1.通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。

2.类内部可以访问私有属性(方法)

3.类外部不能直接访问私有属性(方法)

4.类外部可以通过“类名_私有属性(方法)名”访问私有属性(方法)

【注】方法本质上也是属性,只不过是可以通过()执行而已。所以,此处讲的私有属性和公有属性,也同时讲解了私有方法和公有方法的用法。如下测试中,同时也包含了私有方法和公有方法的例子。

class Employee:
    __company = 'company'

    def __init__(self, name, age):
        self.name = name
        self.__age = age  # 私有属性

    def __work(self):     # 私有方法
        print(Employee.__company)

e = Employee('Cat', 18)

e._Employee__work()
>>> company

print(Employee._Employee__company)
>>> company


print(e._Employee__age)
>>> 18

print(dir(e))
>>> ['_Employee__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']

@property 装饰器

# 公有属性基操
class Employee:
    def __init__(self, salary):
        self.salary = salary   # 改成__salary则不可直接访问

e = Employee(3000)
e.salary = -2000
print(e.salary)
>>> -2000

# 普通方式更改私有属性基操
class Employee1:
    def __init__(self, salary):
        self.__salary = salary

    def get(self):
        return self.__salary

    def set(self,salary):
        if 1000<salary<50000:
            self.__salary = salary
        else:
            print('False')

# 直接e.__salary报错
e = Employee1(3000)
e.set(2000)
print(e.get())
>>> 2000

# @property调用私有属性
class Employee2:
    def __init__(self, salary):
        self.__salary = salary
    @property                  # 相当于get
    def salary(self):
        return self.__salary
    @salary.setter             # 相当于set
    def salary(self,salary):
        if 1000<salary<50000:
            self.__salary = salary
        else:
            print('False')
        

e = Employee2(3000)
e.salary = 2000
print(e.salary)
>>> 2000

面向对象三大特征

封装(利用私有属性和方法)、继承、多态

继承

  • class 子类(父类1,[父类2……]) 可以继承多个父类
  • 私有属性方法被继承,但是不可直接使用
  • 如果在类定义中没有指定父类,则默认父类是object类。也就是说, object是所有类的父类,里面定义了一些所有类共有的默认实现,比如:__new__()
class Person:
    def haha(self):
        print('haha')

class Student():
    pass

s = Student()
s.haha()
>>> haha
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Student(Person):
    def __init__(self, name, age, score):
        Person.__init__(self, name, age)   # 必须是显示函数,否则不调用
        self.score = score

print(Student.mro()) # method resolution order 方法解析顺序,即类的层次结构
>>> [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]

s = Student('Lucy', 18, 60)
print(s.name)
>>> Lucy
class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

class Student(Person):
    def __init__(self, name, age, score):
        Person.__init__(self, name, age)   # 必须是显示函数,否则不调用
        self.score = score
    def __str__(self):  # 使对象可以直接被打印
        return "my name is {0}".format(self.name)

s = Student('Lucy', 18, 60)
print(dir(s))
>>> ['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'score']

print(s._Person__age)
>>> 18

print(s)
>>> my name is Lucy
>>> 

方法的重写

子类可以重新定义父类中的方法,即覆盖父类的方法,相同函数,子类优先

object根类

多重继承

super()获取父类定义(而非对象)

class A:
    def say(self):
        print("A", self)

class B(A):
    def say(self):
        A.say(self)        # 方法1
        super().say()      # 方法2
        print("B", self)

B().say()

多态

class Man:
    pass

class Chinese(Man):
    def eat(self):
        print("chopsticks")

class English(Man):
    def eat(self):
        print("fork")

def ManEat(m):
    if isinstance(m, Man):   # 根据不同对象调用不同方法(Chinese/English)
        m.eat()
    else:
        print("不能吃饭")

ManEat(Chinese)
>>> "不能吃饭"

ManEat(Chinese())
>>> "chopsticks"

特殊方法和运算符重载

# 关于加法
a + b
a.__add__(b)

class Person:
    def __init__(self, name):
        self.name = name
    def __add__(self, other):            # 两个人名
        if isinstance(other, Person):    # 对象类型是否相同
            print('{0}{1}'.format(self.name, other.name))
        else:
            print('类型不同不能相加')
    def __mul__(self, other):            # 乘法
        if isinstance(other, int):
            print(self.name*other)
        else:
            print('类型不同不能相乘')

p1 = Person('cat')
p2 = Person('dog')
print(p1+p2)
>>> catdog

print(p1*5)
>>> catcatcatcatcat

特殊属性

class A:
    pass

class B:
    pass

class C(B,A):
    def __init__(self, nn):
        self.nn = nn
	def cc(self):
		print('haha')

c = C(3)
print(dir(c))
print(c.__dict__)      # 特殊属性
print(c.__class__)
print(C.__bases__)
print(C.mro())
print(A.__subclasses__())

深拷贝和浅拷贝内存

赋值:内外对象不变

浅拷贝:外部对象变化,内部对象不变

深拷贝:全部重新复制

组合

内外对象组合,self.a = a,a可以指对象,通过组合实现继承

class A:
    def say():
        print('AAAA')

class B:
    def __init__(self,a):
        self.a = a

a = A()
b = B(a)
b.a.say()
>>> AAAA
  • “is—a”关系使用继承,从而实现子类拥有的父类的方法和属性。“is—a”关系指的是类似这样的关系:狗是动物, dog is animal,狗类就应该继承动物类

  • “has—a”关系使用组合 ,也能实现一个类拥有另一个类的方法和属性。"has-a"关系指的是这样的关系:手机拥有CPU. MobilePhone has a CPU.

设计模式——工厂模式实现(GOF23)

设计模式——单例模式

单例模式(Singleton Pattern)的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。

单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较多的资源,如读取配置文件、产生其他依赖对象时,可以产一个“单例对象”,然后永久驻留内存中,从而极大的降低开销。

class MySingleton:
    __obj = None        # 用于存放类属性
    __init_flag = True  # 设置只能初始化一次

    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)
        return cls.__obj
    
    def __init__(self.name):
        if MySingleton.__init_flag:
            print("init")
            self.name = name
            MySingleton.__init_flag = False   # 初始化一次后结束

a = MySingleton('a')
b = MySingleton('b')
print(a)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值