#๐Ÿ”’ name mangling

98 messages ยท Page 1 of 1 (latest)

twilit abyss
#

when creating class attributes if you're trying to obfuscate that throuh name mangling does it matter if we use single or double underscore? i.e.:

class cartoons
  def __init__(self, lines, shade):
     self.__lines = lines   # or would it be self._line/self._shade?
     self.__shade = shade
hexed cryptBOT
#

@twilit abyss

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

shell finch
#

why are you trying to obfuscate class attributes?

twilit abyss
#

calling them "private"

#

i guess

#

and using getters to pull out this info

#

im not sure entirely

#

im more so curious about the convention for doing so

#

should it be __ or _

polar inlet
twilit abyss
#

can we just answer the question lol

polar inlet
#

Name mangling only happens with double underscore.

twilit abyss
#

im in class my teacher is using _ but previously i was taught __

polar inlet
#

Single underscore is just nomenclature

shell finch
#

single underscores are conventional for private attributes, but no attributes are truly private in python even if you mangle them

twilit abyss
polar inlet
#

But generally speaking only beginners think they need to make things private when it's usually not the case

twilit abyss
#

wait so it single or double

shell finch
#

also note that implementing getters and setters is usually considered bad practice in python

twilit abyss
#

or are u guys referring to different things?

shell finch
#

because they aren't necessary, there's no purpose

polar inlet
twilit abyss
#

whats the difference between it being mangled or just being private

twilit abyss
polar inlet
#

Single underscore is just the other telling other users of the class that an attribute is intended to not be modified unless you really know what you're doing

shell finch
#

here's how you access an attribute in python:

my_obj.attribute
```simple as
polar inlet
#

Double underscore mangles it which makes it more difficult to modify

twilit abyss
twilit abyss
shell finch
#

they're either talking about a different language or wrong

polar inlet
polar inlet
#

Inside of your class it's still self.__thing

But really nobody uses this in a professional setting

twilit abyss
#

idk if this helps or changes anything

#

but this is suppose to be in the context of data science?

#

this is a data structures and algorithms class

polar inlet
#

Data scientists are notoriously bad programmers

#

So that just adds evidence that your professor is wrong

olive jackal
twilit abyss
#

this is part of some cc class were building using this code she gave us

#
class CreditCard:
    """A consumer credit card."""  # docstring, the first set of comments after the name of class is considered the help for that class. help(CreditCard)

    def __init__(self, customer, bank, acnt, limit):  # The constructor is the very first method
        """Create a new credit card instance.

        The initial balance is zero.

        customer: the name of the customer (e.g., John Bowman )
        bank: the name of the bank (e.g., California Savings )
        acnt : the account identifier (e.g., 5391 0375 9387 5309 )
        limit: credit limit (measured in dollars)
        """
        self.__customer = customer
        self._bank = bank
        self._account = acnt
        self._limit = limit
        self._balance = 0  # we start with a balance of zero, this is private, nobody can change it

    def get_customer(self):  # The get functions are a must, they're called accessor functions (methods)
        """Return name of the customer."""
        return self._customer

    def get_bank(self):
        """Return the bank s name."""
        return self._bank

    def get_account(self):
        """Return the card identifying number (typically stored as a string)."""
        return self._account

    def get_limit(self):
        """Return current credit limit."""
        return self._limit

    def get_balance(self):
        """Return current balance."""
        return self._balance

    def set_limit(self, limit):
        self._limit = limit
polar inlet
twilit abyss
#

so here ur saying the get_blah stuff is unnecessary?

shell finch
#

yep, the set ones are also unnecessary

polar inlet
twilit abyss
#

what would be the best practice way to handle this then

#

if i wanted to change the limit of a card here

olive jackal
twilit abyss
#

or if i wanted to call/get the current balance or something

shell finch
#
class CreditCard:
    """A consumer credit card."""  # docstring, the first set of comments after the name of class is considered the help for that class. help(CreditCard)

    def __init__(self, customer, bank, acnt, limit):  # The constructor is the very first method
        """Create a new credit card instance.

        The initial balance is zero.

        customer: the name of the customer (e.g., John Bowman )
        bank: the name of the bank (e.g., California Savings )
        acnt : the account identifier (e.g., 5391 0375 9387 5309 )
        limit: credit limit (measured in dollars)
        """
        self.customer = customer
        self.bank = bank
        self.account = acnt
        self.limit = limit
        self.balance = 0  # we start with a balance of zero, this is private, nobody can change it

c = CreditCard(...)
c.bank = whatever
print(c.limit)
olive jackal
shell finch
#

@olive jackal we're talking about python here, please stop disrupting

polar inlet
twilit abyss
#

what if u wanted to change the limit?

#

dont you need a function or method for that?

polar inlet
olive jackal
twilit abyss
#

oh that works lol

shell finch
twilit abyss
#

im curious where does this getters/setters thing come from then? like are people just trying to shoehorn this into python from other languages?

shell finch
#

yeah, it comes from java which used to be the default college class language

polar inlet
twilit abyss
#

ah

#

when i look like this

shell finch
#

to be clear, if your professor requires you write code like this you should, and then you should stop when you leave their class

twilit abyss
#

it seems the getter method is just overly redundant in a not good way

polar inlet
#

It even might be the case with your professor...

Often languages used in teaching are a department decision at universities

twilit abyss
#

if i just access these attributes directly

olive jackal
#

i think writing setter and getter in python is a good practice, even if you can't make the attributes private

twilit abyss
shell hill
#

I want to chime in briefly and say that sometimes it makes sense to use a sort-of implementation of getters/setters in Python. If you're interested in checking that out, check out the @property decorator Python has.

It still keeps the typical Python way of accessing attributes, but also lets you control a bit more of the getter/setter process.

For instance, sometimes I need to do a bit of work between how I store the value internally and what I want to give to the user. A setter/getter makes sense there.

polar inlet
shell finch
#

yeah, i removed the leading underscores because now those attributes are meant to be accessed from outside the class

shell finch
#

sometimes you have an attribute that is meant to be only used internal to the class, which you can indicate with the underscore, but it changes nothing about the behavior

polar inlet
#
class foo:
    def __init__(self):
        self._a = 0
        self.__b = 1

bar = foo()
print(bar._a) #works
print(bar.__b) # doesn't work
#

Now the mangling happens in a predictable way... I never fully remember it without googling it (because again people don't actually do this professionally)

But if you know how it's mangled you can just write that and it works too

#

But Kat is not wrong. Sometimes it makes sense to have getters and setters. It sort of depends on the environment and if you trust the users of your code

shell finch
#

it looks like _CreditCard__customer

polar inlet
#

Yeah bar._foo__b in my example

lunar cobalt
# twilit abyss when creating class attributes if you're trying to obfuscate that throuh name ma...

Mangling happens with double leading underscore. Did you look at PEP 8? (https://peps.python.org/pep-0008/#method-names-and-instance-variables)

shell finch
#

@lunar cobalt did you just ignore this entire thread?

twilit abyss
twilit abyss
shell hill
shell finch
#

!e

class CreditCard:

    def __init__(self, customer, bank, acnt, limit):
        self.__customer = customer
        self.bank = bank
        self.account = acnt
        self.limit = limit
        self._balance = 10

    @property
    def balance(self):
        return self._balance + 1 # everybody gets an extra one
    
    @balance.setter
    def balance(self, new_val):
        if new_val > self._balance:
            raise ValueError("nice try")
        else:
            self._balance = new_val

c = CreditCard(1, 2, 3, 4)
print(c.balance)
c.balance = 8
print(c.balance)
c.balance = 100
hexed cryptBOT
shell finch
#

the useful part of getters and setters is when you want to do something beyond simply getting or setting the value
you can do that in python with the property decorator, and still access that attribute as normal, as shown ^

shell hill
#

So, the usual getter/setter methodology isn't really a thing in Python. By that I mean something like get_temperature() or set_temperature(). In python we would just do thing.temperature or thing.temperature = 10.

But sometimes we do want a bit more control of what the user is allowed to set and what we give the user when they ask for a value.

For instance, if we're dealing with temperature in units of Kelvin, maybe we want to entirely prevent the user from trying to set the temperature to a negative number (because you can't have negative temperature in Kelvin (for physics folks watching, don't get pedantic with me)).

#

Also what Scofflaw said

shell finch
twilit abyss
shell finch
#

that's the python design philosophy

hexed cryptBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.